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
|
# common compile options
|
||||||
add_definitions( -DVERSION="${GRIVE_VERSION}" )
|
add_definitions( -DVERSION="${GRIVE_VERSION}" )
|
||||||
add_definitions( -D_FILE_OFFSET_BITS=64 )
|
add_definitions( -D_FILE_OFFSET_BITS=64 )
|
||||||
|
add_definitions( -DPROJ_NS=gr )
|
||||||
|
|
||||||
add_subdirectory( libgrive )
|
add_subdirectory( libgrive )
|
||||||
add_subdirectory( grive )
|
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>
|
|
@ -32,7 +32,7 @@
|
||||||
#include "util/Crypt.hh"
|
#include "util/Crypt.hh"
|
||||||
#include "util/log/Log.hh"
|
#include "util/log/Log.hh"
|
||||||
#include "util/OS.hh"
|
#include "util/OS.hh"
|
||||||
#include "util/StdioFile.hh"
|
#include "util/File.hh"
|
||||||
#include "xml/Node.hh"
|
#include "xml/Node.hh"
|
||||||
#include "xml/NodeSet.hh"
|
#include "xml/NodeSet.hh"
|
||||||
#include "xml/String.hh"
|
#include "xml/String.hh"
|
||||||
|
@ -269,7 +269,7 @@ void Resource::FromLocal( const DateTime& last_sync )
|
||||||
else
|
else
|
||||||
m_state = ( m_mtime > last_sync ? local_new : remote_deleted ) ;
|
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_kind = fs::is_directory(path) ? "folder" : "file" ;
|
||||||
m_md5 = fs::is_directory(path) ? "" : crypt::MD5::Get( path ) ;
|
m_md5 = fs::is_directory(path) ? "" : crypt::MD5::Get( path ) ;
|
||||||
}
|
}
|
||||||
|
@ -583,7 +583,7 @@ bool Resource::Upload(
|
||||||
{
|
{
|
||||||
assert( http != 0 ) ;
|
assert( http != 0 ) ;
|
||||||
|
|
||||||
StdioFile file( Path() ) ;
|
File file( Path() ) ;
|
||||||
std::ostringstream xcontent_len ;
|
std::ostringstream xcontent_len ;
|
||||||
xcontent_len << "X-Upload-Content-Length: " << file.Size() ;
|
xcontent_len << "X-Upload-Content-Length: " << file.Size() ;
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "http/Agent.hh"
|
#include "http/Agent.hh"
|
||||||
#include "util/Crypt.hh"
|
#include "util/Crypt.hh"
|
||||||
|
#include "util/File.hh"
|
||||||
#include "util/log/Log.hh"
|
#include "util/log/Log.hh"
|
||||||
#include "protocol/Json.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 )
|
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) )
|
if ( IsIgnore(fname) )
|
||||||
Log( "file %1% is ignored by grive", fname, log::verbose ) ;
|
Log( "file %1% is ignored by grive", fname, log::verbose ) ;
|
||||||
|
@ -228,7 +229,8 @@ void State::Read( const fs::path& filename )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Json json = Json::ParseFile( filename.string() ) ;
|
File file( filename ) ;
|
||||||
|
Json json = Json::Parse( &file ) ;
|
||||||
|
|
||||||
Json last_sync = json["last_sync"] ;
|
Json last_sync = json["last_sync"] ;
|
||||||
m_last_sync.Assign(
|
m_last_sync.Assign(
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
namespace gr {
|
namespace gr {
|
||||||
|
|
||||||
class StdioFile ;
|
class File ;
|
||||||
|
|
||||||
namespace http {
|
namespace http {
|
||||||
|
|
||||||
|
@ -33,6 +33,8 @@ class Receivable ;
|
||||||
class Agent
|
class Agent
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
|
virtual ~Agent() {}
|
||||||
|
|
||||||
virtual long Put(
|
virtual long Put(
|
||||||
const std::string& url,
|
const std::string& url,
|
||||||
const std::string& data,
|
const std::string& data,
|
||||||
|
@ -41,7 +43,7 @@ public :
|
||||||
|
|
||||||
virtual long Put(
|
virtual long Put(
|
||||||
const std::string& url,
|
const std::string& url,
|
||||||
StdioFile& file,
|
File& file,
|
||||||
Receivable *dest,
|
Receivable *dest,
|
||||||
const Header& hdr ) = 0 ;
|
const Header& hdr ) = 0 ;
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "Receivable.hh"
|
#include "Receivable.hh"
|
||||||
|
|
||||||
#include "util/log/Log.hh"
|
#include "util/log/Log.hh"
|
||||||
#include "util/StdioFile.hh"
|
#include "util/File.hh"
|
||||||
|
|
||||||
#include <boost/throw_exception.hpp>
|
#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 ;
|
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( ptr != 0 ) ;
|
||||||
assert( file != 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() ) ;
|
assert( count <= std::numeric_limits<std::size_t>::max() ) ;
|
||||||
|
|
||||||
if ( count > 0 )
|
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 ;
|
return count ;
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ long CurlAgent::Put(
|
||||||
|
|
||||||
long CurlAgent::Put(
|
long CurlAgent::Put(
|
||||||
const std::string& url,
|
const std::string& url,
|
||||||
StdioFile& file,
|
File& file,
|
||||||
Receivable *dest,
|
Receivable *dest,
|
||||||
const Header& hdr )
|
const Header& hdr )
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,7 +47,7 @@ public :
|
||||||
|
|
||||||
long Put(
|
long Put(
|
||||||
const std::string& url,
|
const std::string& url,
|
||||||
StdioFile& file,
|
File& file,
|
||||||
Receivable *dest,
|
Receivable *dest,
|
||||||
const Header& hdr ) ;
|
const Header& hdr ) ;
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ std::size_t Download::OnData( void *data, std::size_t count )
|
||||||
if ( m_crypt.get() != 0 )
|
if ( m_crypt.get() != 0 )
|
||||||
m_crypt->Write( data, count ) ;
|
m_crypt->Write( data, count ) ;
|
||||||
|
|
||||||
return m_file.Write( data, count ) ;
|
return m_file.Write( static_cast<char*>(data), count ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
} } // end of namespace
|
} } // end of namespace
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Receivable.hh"
|
#include "Receivable.hh"
|
||||||
#include "util/StdioFile.hh"
|
#include "util/File.hh"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ public :
|
||||||
std::size_t OnData( void *data, std::size_t count ) ;
|
std::size_t OnData( void *data, std::size_t count ) ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
StdioFile m_file ;
|
File m_file ;
|
||||||
std::auto_ptr<crypt::MD5> m_crypt ;
|
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
|
class Receivable
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
|
virtual ~Receivable() {}
|
||||||
virtual std::size_t OnData( void *data, std::size_t count ) = 0 ;
|
virtual std::size_t OnData( void *data, std::size_t count ) = 0 ;
|
||||||
virtual void Clear() = 0 ;
|
virtual void Clear() = 0 ;
|
||||||
} ;
|
} ;
|
||||||
|
|
|
@ -62,7 +62,7 @@ long AuthAgent::Put(
|
||||||
|
|
||||||
long AuthAgent::Put(
|
long AuthAgent::Put(
|
||||||
const std::string& url,
|
const std::string& url,
|
||||||
StdioFile& file,
|
File& file,
|
||||||
Receivable *dest,
|
Receivable *dest,
|
||||||
const Header& hdr )
|
const Header& hdr )
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,7 +44,7 @@ public :
|
||||||
|
|
||||||
long Put(
|
long Put(
|
||||||
const std::string& url,
|
const std::string& url,
|
||||||
StdioFile& file,
|
File& file,
|
||||||
http::Receivable *dest,
|
http::Receivable *dest,
|
||||||
const http::Header& hdr ) ;
|
const http::Header& hdr ) ;
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,21 @@
|
||||||
|
|
||||||
#include "Json.hh"
|
#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/json_tokener.h>
|
||||||
#include <json/linkhash.h>
|
#include <json/linkhash.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -35,7 +46,10 @@ Json::Json( ) :
|
||||||
m_json( ::json_object_new_object() )
|
m_json( ::json_object_new_object() )
|
||||||
{
|
{
|
||||||
if ( m_json == 0 )
|
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 ) :
|
Json::Json( const char *str ) :
|
||||||
|
@ -43,43 +57,88 @@ Json::Json( const char *str ) :
|
||||||
{
|
{
|
||||||
if ( m_json == 0 )
|
if ( m_json == 0 )
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
Error() << expt::ErrMsg( "cannot create json string \"" + std::string(str) + "\"" ) ) ;
|
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 <>
|
template <>
|
||||||
Json::Json( const std::string& str ) :
|
Json::Json( const std::string& str ) :
|
||||||
m_json( ::json_object_new_string( str.c_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 )
|
if ( m_json == 0 )
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
Error() << expt::ErrMsg( "cannot create json string \"" + str + "\"" ) ) ;
|
Error()
|
||||||
|
<< JsonCApi_( "json_object_new_double" )
|
||||||
// paranoid check
|
<< ValueErr( val )
|
||||||
assert( ::json_object_get_string( m_json ) == str ) ;
|
) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
Json::Json( const int& l ) :
|
Json::Json( const boost::int32_t& l ) :
|
||||||
m_json( ::json_object_new_int( l ) )
|
m_json( ::json_object_new_int( l ) )
|
||||||
{
|
{
|
||||||
if ( m_json == 0 )
|
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 <>
|
template <>
|
||||||
Json::Json( const long& l ) :
|
Json::Json( const boost::int64_t& l ) :
|
||||||
m_json( ::json_object_new_int( static_cast<int>(l) ) )
|
m_json( ::json_object_new_int64( l ) )
|
||||||
{
|
{
|
||||||
if ( m_json == 0 )
|
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 <>
|
template <>
|
||||||
Json::Json( const unsigned long& l ) :
|
Json::Json( const boost::uint32_t& l ) :
|
||||||
m_json( ::json_object_new_int( static_cast<int>(l) ) )
|
m_json( ::json_object_new_int( static_cast<int>(l) ) )
|
||||||
{
|
{
|
||||||
if ( m_json == 0 )
|
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 <>
|
template <>
|
||||||
|
@ -87,7 +146,7 @@ Json::Json( const std::vector<Json>& arr ) :
|
||||||
m_json( ::json_object_new_array( ) )
|
m_json( ::json_object_new_array( ) )
|
||||||
{
|
{
|
||||||
if ( m_json == 0 )
|
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 )
|
for ( std::vector<Json>::const_iterator i = arr.begin() ; i != arr.end() ; ++i )
|
||||||
Add( *i ) ;
|
Add( *i ) ;
|
||||||
|
@ -98,7 +157,11 @@ Json::Json( const bool& b ) :
|
||||||
m_json( ::json_object_new_boolean( b ) )
|
m_json( ::json_object_new_boolean( b ) )
|
||||||
{
|
{
|
||||||
if ( m_json == 0 )
|
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 <>
|
template <>
|
||||||
|
@ -106,7 +169,7 @@ Json::Json( const Object& obj ) :
|
||||||
m_json( ::json_object_new_object() )
|
m_json( ::json_object_new_object() )
|
||||||
{
|
{
|
||||||
if ( m_json == 0 )
|
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 )
|
for ( Object::const_iterator i = obj.begin() ; i != obj.end() ; ++i )
|
||||||
Add( i->first, i->second ) ;
|
Add( i->first, i->second ) ;
|
||||||
|
@ -157,13 +220,15 @@ Json Json::operator[]( const std::string& key ) const
|
||||||
{
|
{
|
||||||
assert( m_json != 0 ) ;
|
assert( m_json != 0 ) ;
|
||||||
|
|
||||||
struct json_object *j = ::json_object_object_get( m_json, key.c_str() ) ;
|
struct json_object *j = 0 ;
|
||||||
if ( j == 0 )
|
if ( !::json_object_object_get_ex( m_json, key.c_str(), &j ) )
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
Error()
|
Error()
|
||||||
<< expt::ErrMsg( "key: " + key + " is not found in object" )
|
<< JsonCApi_( "json_object_object_get" )
|
||||||
<< JsonInfo( *this ) ) ;
|
<< KeyNotFound_( key )
|
||||||
|
<< Json_( ::json_object_to_json_string(m_json) ) ) ;
|
||||||
|
|
||||||
|
assert( j != 0 ) ;
|
||||||
return Json( j ) ;
|
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 ) ;
|
struct json_object *j = ::json_object_array_get_idx( m_json, idx ) ;
|
||||||
if ( j == 0 )
|
if ( j == 0 )
|
||||||
{
|
{
|
||||||
std::ostringstream ss ;
|
|
||||||
ss << "index " << idx << " is not found in array" ;
|
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
Error()
|
Error()
|
||||||
<< expt::ErrMsg( ss.str() )
|
<< JsonCApi_( "json_object_array_get_idx" )
|
||||||
<< JsonInfo( *this ) ) ;
|
<< OutOfRange_( idx )
|
||||||
|
<< Json_( ::json_object_to_json_string(m_json) ) ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Json( j ) ;
|
return Json( j ) ;
|
||||||
|
@ -188,15 +252,17 @@ Json Json::operator[]( const std::size_t& idx ) const
|
||||||
bool Json::Has( const std::string& key ) const
|
bool Json::Has( const std::string& key ) const
|
||||||
{
|
{
|
||||||
assert( m_json != 0 ) ;
|
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
|
bool Json::Get( const std::string& key, Json& json ) const
|
||||||
{
|
{
|
||||||
assert( m_json != 0 ) ;
|
assert( m_json != 0 ) ;
|
||||||
struct json_object *j = ::json_object_object_get( m_json, key.c_str() ) ;
|
struct json_object *j = 0 ;
|
||||||
if ( j != 0 )
|
if ( ::json_object_object_get_ex( m_json, key.c_str(), &j ) )
|
||||||
{
|
{
|
||||||
|
assert( j != 0 ) ;
|
||||||
|
|
||||||
Json tmp( j ) ;
|
Json tmp( j ) ;
|
||||||
json.Swap( tmp ) ;
|
json.Swap( tmp ) ;
|
||||||
return true ;
|
return true ;
|
||||||
|
@ -226,14 +292,20 @@ void Json::Add( const Json& json )
|
||||||
bool Json::Bool() const
|
bool Json::Bool() const
|
||||||
{
|
{
|
||||||
assert( m_json != 0 ) ;
|
assert( m_json != 0 ) ;
|
||||||
return ::json_object_get_boolean( m_json ) ;
|
return ::json_object_get_boolean( m_json ) == TRUE ;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
bool Json::Is<bool>() const
|
bool Json::Is<bool>() const
|
||||||
{
|
{
|
||||||
assert( m_json != 0 ) ;
|
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
|
std::string Json::Str() const
|
||||||
|
@ -246,7 +318,13 @@ template <>
|
||||||
bool Json::Is<std::string>() const
|
bool Json::Is<std::string>() const
|
||||||
{
|
{
|
||||||
assert( m_json != 0 ) ;
|
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
|
int Json::Int() const
|
||||||
|
@ -259,7 +337,31 @@ template <>
|
||||||
bool Json::Is<int>() const
|
bool Json::Is<int>() const
|
||||||
{
|
{
|
||||||
assert( m_json != 0 ) ;
|
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 )
|
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 ) ;
|
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 ) ;
|
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
|
Json::Type Json::DataType() const
|
||||||
|
@ -296,7 +400,13 @@ template <>
|
||||||
bool Json::Is<Json::Object>() const
|
bool Json::Is<Json::Object>() const
|
||||||
{
|
{
|
||||||
assert( m_json != 0 ) ;
|
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
|
Json::Array Json::AsArray() const
|
||||||
|
@ -314,9 +424,18 @@ template <>
|
||||||
bool Json::Is<Json::Array>() const
|
bool Json::Is<Json::Array>() const
|
||||||
{
|
{
|
||||||
assert( m_json != 0 ) ;
|
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
|
Json Json::FindInArray( const std::string& key, const std::string& value ) const
|
||||||
{
|
{
|
||||||
std::size_t count = ::json_object_array_length( m_json ) ;
|
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 )
|
if ( item.Has(key) && item[key].Str() == value )
|
||||||
return item ;
|
return item ;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_THROW_EXCEPTION(
|
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
|
bool Json::FindInArray( const std::string& key, const std::string& value, Json& result ) const
|
||||||
|
@ -340,36 +467,57 @@ bool Json::FindInArray( const std::string& key, const std::string& value, Json&
|
||||||
}
|
}
|
||||||
catch ( Error& )
|
catch ( Error& )
|
||||||
{
|
{
|
||||||
return false ;
|
|
||||||
}
|
}
|
||||||
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
Json Json::Parse( const std::string& str )
|
Json Json::Parse( const std::string& str )
|
||||||
{
|
{
|
||||||
struct json_object *json = ::json_tokener_parse( str.c_str() ) ;
|
struct json_object *json = ::json_tokener_parse( str.c_str() ) ;
|
||||||
if ( json == 0 )
|
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() ) ;
|
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_tokener *tok = ::json_tokener_new() ;
|
||||||
struct json_object *json = 0 ;
|
struct json_object *json = 0 ;
|
||||||
|
|
||||||
char buf[1024] ;
|
char buf[1024] ;
|
||||||
std::size_t count = 0 ;
|
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 ) ;
|
json = ::json_tokener_parse_ex( tok, buf, count ) ;
|
||||||
|
|
||||||
if ( json == 0 )
|
// check for parse error
|
||||||
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( ::json_tokener_errors[tok->err] ) ) ;
|
if ( ::json_tokener_get_error(tok) == ::json_tokener_continue )
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
|
||||||
::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() ) ;
|
return Json( json, NotOwned() ) ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,13 @@ struct json_object ;
|
||||||
|
|
||||||
namespace gr {
|
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
|
class Json
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
|
@ -38,19 +43,35 @@ public :
|
||||||
typedef std::vector<Json> Array ;
|
typedef std::vector<Json> Array ;
|
||||||
|
|
||||||
struct Error : virtual Exception {} ;
|
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 :
|
public :
|
||||||
template <typename T>
|
template <typename T>
|
||||||
explicit Json( const T& val ) ;
|
explicit Json( const T& val ) ;
|
||||||
|
|
||||||
|
template <std::size_t n>
|
||||||
|
explicit Json( const char (&str)[n] ) :
|
||||||
|
m_json( InitStr( str, n ) )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Json() ;
|
Json() ;
|
||||||
Json( const Json& rhs ) ;
|
Json( const Json& rhs ) ;
|
||||||
Json( const char *str ) ;
|
Json( const char *str ) ;
|
||||||
~Json() ;
|
~Json() ;
|
||||||
|
|
||||||
static Json Parse( const std::string& str ) ;
|
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::string& key ) const ;
|
||||||
Json operator[]( const std::size_t& idx ) const ;
|
Json operator[]( const std::size_t& idx ) const ;
|
||||||
|
@ -68,6 +89,9 @@ public :
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool Is() const ;
|
bool Is() const ;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T As() const ;
|
||||||
|
|
||||||
bool Has( const std::string& key ) const ;
|
bool Has( const std::string& key ) const ;
|
||||||
bool Get( const std::string& key, Json& json ) const ;
|
bool Get( const std::string& key, Json& json ) const ;
|
||||||
void Add( const std::string& key, const Json& json ) ;
|
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 ;
|
bool FindInArray( const std::string& key, const std::string& value, Json& result ) const ;
|
||||||
|
|
||||||
friend std::ostream& operator<<( std::ostream& os, const Json& json ) ;
|
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 } ;
|
enum Type { null_type, bool_type, double_type, int_type, object_type, array_type, string_type } ;
|
||||||
|
|
||||||
|
@ -88,8 +112,15 @@ private :
|
||||||
struct NotOwned {} ;
|
struct NotOwned {} ;
|
||||||
Json( struct json_object *json, 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 :
|
private :
|
||||||
public :
|
|
||||||
struct json_object *m_json ;
|
struct json_object *m_json ;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
#include "Config.hh"
|
#include "Config.hh"
|
||||||
|
|
||||||
#include "util/StdioFile.hh"
|
#include "util/File.hh"
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
namespace gr {
|
namespace PROJ_NS {
|
||||||
|
|
||||||
const std::string default_filename = ".grive";
|
const std::string default_filename = ".grive";
|
||||||
const char *env_name = "GR_CONFIG";
|
const char *env_name = "GR_CONFIG";
|
||||||
|
@ -64,8 +64,8 @@ const fs::path Config::Filename() const
|
||||||
|
|
||||||
void Config::Save( )
|
void Config::Save( )
|
||||||
{
|
{
|
||||||
StdioFile file( m_path.string(), 0600 ) ;
|
gr::File file( m_path.string(), 0600 ) ;
|
||||||
m_file.Write( file ) ;
|
m_file.Write( &file ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::Set( const std::string& key, const Json& value )
|
void Config::Set( const std::string& key, const Json& value )
|
||||||
|
@ -93,7 +93,8 @@ Json Config::Read()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Json::ParseFile( m_path.string() ) ;
|
gr::File file(m_path) ;
|
||||||
|
return Json::Parse( &file ) ;
|
||||||
}
|
}
|
||||||
catch ( Exception& e )
|
catch ( Exception& e )
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace boost
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace gr {
|
namespace PROJ_NS {
|
||||||
|
|
||||||
class Config
|
class Config
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
#include "Crypt.hh"
|
#include "Crypt.hh"
|
||||||
|
|
||||||
#include "StdioFile.hh"
|
#include "File.hh"
|
||||||
#include "Exception.hh"
|
#include "Exception.hh"
|
||||||
#include "MemMap.hh"
|
#include "MemMap.hh"
|
||||||
|
|
||||||
|
@ -76,16 +76,16 @@ std::string MD5::Get( const fs::path& file )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
StdioFile sfile( file ) ;
|
File sfile( file ) ;
|
||||||
return Get( sfile ) ;
|
return Get( sfile ) ;
|
||||||
}
|
}
|
||||||
catch ( StdioFile::Error& )
|
catch ( File::Error& )
|
||||||
{
|
{
|
||||||
return "" ;
|
return "" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MD5::Get( StdioFile& file )
|
std::string MD5::Get( File& file )
|
||||||
{
|
{
|
||||||
MD5 crypt ;
|
MD5 crypt ;
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
namespace gr {
|
namespace gr {
|
||||||
|
|
||||||
class StdioFile ;
|
class File ;
|
||||||
|
|
||||||
namespace crypt {
|
namespace crypt {
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ public :
|
||||||
MD5() ;
|
MD5() ;
|
||||||
~MD5() ;
|
~MD5() ;
|
||||||
|
|
||||||
static std::string Get( StdioFile& file ) ;
|
static std::string Get( File& file ) ;
|
||||||
static std::string Get( const boost::filesystem::path& file ) ;
|
static std::string Get( const boost::filesystem::path& file ) ;
|
||||||
|
|
||||||
void Write( const void *data, std::size_t size ) ;
|
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.
|
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/Backtrace.hh"
|
||||||
#include "bfd/Debug.hh"
|
#include "bfd/Debug.hh"
|
||||||
|
@ -28,15 +28,20 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace gr {
|
namespace PROJ_NS {
|
||||||
|
|
||||||
class Backtrace ;
|
class Backtrace ;
|
||||||
|
|
||||||
Exception::Exception( )
|
Exception::Exception( )
|
||||||
{
|
{
|
||||||
#ifdef HAVE_BFD
|
#ifdef HAVE_BFD
|
||||||
*this << expt::BacktraceInfo( Backtrace() ) ;
|
*this << expt::Backtrace_( Backtrace() ) ;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* Exception::what() const throw()
|
||||||
|
{
|
||||||
|
return boost::diagnostic_information_what( *this ) ;
|
||||||
|
}
|
||||||
|
|
||||||
} // end of namespace
|
} // 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
|
Copyright (C) 2012 Wan Wai Ho
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
|
@ -25,54 +25,35 @@
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace gr {
|
namespace PROJ_NS {
|
||||||
|
|
||||||
class Backtrace ;
|
class Backtrace ;
|
||||||
|
|
||||||
/** \defgroup exception Exception Classes
|
/** \defgroup exception Exception Classes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// base class for exception in libpdfdoc
|
/** \brief base class for exception in WebWrite
|
||||||
/** \ingroup exception
|
\ingroup exception
|
||||||
This class is the base class for all exception class in libpdfdoc.
|
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 :
|
struct Exception :
|
||||||
virtual public std::exception,
|
virtual public std::exception,
|
||||||
virtual public boost::exception
|
virtual public boost::exception
|
||||||
{
|
{
|
||||||
Exception( ) ;
|
Exception( ) ;
|
||||||
|
|
||||||
|
virtual const char* what() const throw() ;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
struct FileError : virtual Exception {} ;
|
/// Exception informations
|
||||||
|
|
||||||
/// 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
|
|
||||||
namespace expt
|
namespace expt
|
||||||
{
|
{
|
||||||
// back-trace information. should be present for all exceptions
|
// 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
|
/// generic error message
|
||||||
typedef boost::error_info<struct MsgTag, std::string> ErrMsg ;
|
typedef boost::error_info<struct MsgTag, std::string> ErrMsg ;
|
||||||
|
|
||||||
// nested exception
|
|
||||||
typedef boost::error_info<struct ExceptionTag, Exception> Nested ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of namespace
|
} // end of namespace
|
||||||
|
|
|
@ -17,27 +17,34 @@
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "StdioFile.hh"
|
#include "File.hh"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
// boost headers
|
// boost headers
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
#include <boost/exception/errinfo_api_function.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_errno.hpp>
|
||||||
#include <boost/exception/errinfo_file_name.hpp>
|
#include <boost/exception/errinfo_file_name.hpp>
|
||||||
#include <boost/exception/errinfo_file_open_mode.hpp>
|
#include <boost/exception/errinfo_file_open_mode.hpp>
|
||||||
#include <boost/exception/info.hpp>
|
#include <boost/exception/info.hpp>
|
||||||
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <io.h>
|
||||||
|
typedef int ssize_t ;
|
||||||
|
#else
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// local functions
|
// local functions
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
using namespace gr ;
|
||||||
|
|
||||||
off_t LSeek( int fd, off_t offset, int whence )
|
off_t LSeek( int fd, off_t offset, int whence )
|
||||||
{
|
{
|
||||||
assert( fd >= 0 ) ;
|
assert( fd >= 0 ) ;
|
||||||
|
@ -46,7 +53,7 @@ off_t LSeek( int fd, off_t offset, int whence )
|
||||||
if ( r == static_cast<off_t>(-1) )
|
if ( r == static_cast<off_t>(-1) )
|
||||||
{
|
{
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
gr::StdioFile::Error()
|
File::Error()
|
||||||
<< boost::errinfo_api_function("lseek")
|
<< boost::errinfo_api_function("lseek")
|
||||||
<< boost::errinfo_errno(errno)
|
<< boost::errinfo_errno(errno)
|
||||||
) ;
|
) ;
|
||||||
|
@ -61,7 +68,7 @@ struct stat FStat( int fd )
|
||||||
if ( ::fstat( fd, &s ) != 0 )
|
if ( ::fstat( fd, &s ) != 0 )
|
||||||
{
|
{
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
gr::StdioFile::Error()
|
File::Error()
|
||||||
<< boost::errinfo_api_function("fstat")
|
<< boost::errinfo_api_function("fstat")
|
||||||
<< boost::errinfo_errno(errno)
|
<< boost::errinfo_errno(errno)
|
||||||
) ;
|
) ;
|
||||||
|
@ -71,28 +78,40 @@ struct stat FStat( int fd )
|
||||||
|
|
||||||
} // end of local functions
|
} // 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 ) ;
|
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 ) ;
|
OpenForWrite( path, mode ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
StdioFile::~StdioFile( )
|
/** The destructor will close the file.
|
||||||
|
*/
|
||||||
|
File::~File( )
|
||||||
{
|
{
|
||||||
Close() ;
|
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() )
|
if ( IsOpened() )
|
||||||
Close() ;
|
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() )
|
if ( IsOpened() )
|
||||||
{
|
{
|
||||||
|
@ -129,12 +156,15 @@ void StdioFile::Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StdioFile::IsOpened() const
|
bool File::IsOpened() const
|
||||||
{
|
{
|
||||||
return m_fd != -1 ;
|
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() ) ;
|
assert( IsOpened() ) ;
|
||||||
ssize_t count = ::read( m_fd, ptr, size ) ;
|
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 ;
|
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() ) ;
|
assert( IsOpened() ) ;
|
||||||
ssize_t count = ::write( m_fd, ptr, size ) ;
|
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(
|
BOOST_THROW_EXCEPTION(
|
||||||
Error()
|
Error()
|
||||||
<< boost::errinfo_api_function("read")
|
<< boost::errinfo_api_function("write")
|
||||||
<< boost::errinfo_errno(errno)
|
<< boost::errinfo_errno(errno)
|
||||||
) ;
|
) ;
|
||||||
}
|
}
|
||||||
return count ;
|
return count ;
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t StdioFile::Seek( off_t offset, int whence )
|
off_t File::Seek( off_t offset, int whence )
|
||||||
{
|
{
|
||||||
assert( IsOpened() ) ;
|
assert( IsOpened() ) ;
|
||||||
return LSeek( m_fd, offset, whence ) ;
|
return LSeek( m_fd, offset, whence ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t StdioFile::Tell() const
|
off_t File::Tell() const
|
||||||
{
|
{
|
||||||
assert( IsOpened() ) ;
|
assert( IsOpened() ) ;
|
||||||
return LSeek( m_fd, 0, SEEK_CUR ) ;
|
return LSeek( m_fd, 0, SEEK_CUR ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64_t StdioFile::Size() const
|
u64_t File::Size() const
|
||||||
{
|
{
|
||||||
assert( IsOpened() ) ;
|
assert( IsOpened() ) ;
|
||||||
|
|
||||||
|
@ -186,10 +216,10 @@ u64_t StdioFile::Size() const
|
||||||
return static_cast<uint64_t>( s.st_size ) ;
|
return static_cast<uint64_t>( s.st_size ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StdioFile::Chmod( int mode )
|
void File::Chmod( int mode )
|
||||||
{
|
{
|
||||||
assert( IsOpened() ) ;
|
assert( IsOpened() ) ;
|
||||||
|
#ifndef WIN32
|
||||||
if ( ::fchmod( m_fd, mode ) != 0 )
|
if ( ::fchmod( m_fd, mode ) != 0 )
|
||||||
{
|
{
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
|
@ -198,12 +228,18 @@ void StdioFile::Chmod( int mode )
|
||||||
<< boost::errinfo_errno(errno)
|
<< 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() ) ;
|
assert( IsOpened() ) ;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
assert( false ) ;
|
||||||
|
return 0 ;
|
||||||
|
#else
|
||||||
void *addr = ::mmap( 0, length, PROT_READ, MAP_PRIVATE, m_fd, offset ) ;
|
void *addr = ::mmap( 0, length, PROT_READ, MAP_PRIVATE, m_fd, offset ) ;
|
||||||
if ( addr == reinterpret_cast<void*>( -1 ) )
|
if ( addr == reinterpret_cast<void*>( -1 ) )
|
||||||
{
|
{
|
||||||
|
@ -214,10 +250,12 @@ void* StdioFile::Map( off_t offset, std::size_t length )
|
||||||
) ;
|
) ;
|
||||||
}
|
}
|
||||||
return addr ;
|
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 )
|
if ( ::munmap( addr, length ) != 0 )
|
||||||
{
|
{
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
|
@ -226,6 +264,21 @@ void StdioFile::UnMap( void *addr, std::size_t length )
|
||||||
<< boost::errinfo_errno(errno)
|
<< 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
|
} // end of namespace
|
|
@ -19,32 +19,47 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "DataStream.hh"
|
||||||
#include "Exception.hh"
|
#include "Exception.hh"
|
||||||
#include "FileSystem.hh"
|
#include "FileSystem.hh"
|
||||||
#include "Types.hh"
|
#include "Types.hh"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
struct stat ;
|
||||||
|
|
||||||
namespace gr {
|
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 :
|
public :
|
||||||
|
/// File specific errors. It often includes
|
||||||
|
/// boost::errinfo_api_function and boost::errinfo_errno for the
|
||||||
|
/// detail information.
|
||||||
struct Error : virtual Exception {} ;
|
struct Error : virtual Exception {} ;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
StdioFile() ;
|
File() ;
|
||||||
StdioFile( const fs::path& path ) ;
|
File( const fs::path& path ) ;
|
||||||
StdioFile( const fs::path& path, int mode ) ;
|
File( const fs::path& path, int mode ) ;
|
||||||
~StdioFile( ) ;
|
~File( ) ;
|
||||||
|
|
||||||
|
File( const File& rhs ) ;
|
||||||
|
File& operator=( const File& rhs ) ;
|
||||||
|
void Swap( File& other ) ;
|
||||||
|
|
||||||
void OpenForRead( const fs::path& path ) ;
|
void OpenForRead( const fs::path& path ) ;
|
||||||
void OpenForWrite( const fs::path& path, int mode = 0600 ) ;
|
void OpenForWrite( const fs::path& path, int mode = 0600 ) ;
|
||||||
void Close() ;
|
void Close() ;
|
||||||
bool IsOpened() const ;
|
bool IsOpened() const ;
|
||||||
|
|
||||||
std::size_t Read( void *ptr, std::size_t size ) ;
|
std::size_t Read( char *ptr, std::size_t size ) ;
|
||||||
std::size_t Write( const void *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 Seek( off_t offset, int whence ) ;
|
||||||
off_t Tell() const ;
|
off_t Tell() const ;
|
||||||
|
@ -55,6 +70,8 @@ public :
|
||||||
void* Map( off_t offset, std::size_t length ) ;
|
void* Map( off_t offset, std::size_t length ) ;
|
||||||
static void UnMap( void *addr, std::size_t length ) ;
|
static void UnMap( void *addr, std::size_t length ) ;
|
||||||
|
|
||||||
|
struct stat Stat() const ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
void Open( const fs::path& path, int flags, int mode ) ;
|
void Open( const fs::path& path, int flags, int mode ) ;
|
||||||
|
|
|
@ -25,17 +25,4 @@
|
||||||
namespace gr
|
namespace gr
|
||||||
{
|
{
|
||||||
namespace fs = boost::filesystem ;
|
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 "MemMap.hh"
|
||||||
#include "StdioFile.hh"
|
#include "File.hh"
|
||||||
|
|
||||||
namespace gr {
|
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_addr ( file.Map( offset, length ) ),
|
||||||
m_length( length )
|
m_length( length )
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,7 @@ MemMap::MemMap( StdioFile& file, off_t offset, std::size_t length ) :
|
||||||
|
|
||||||
MemMap::~MemMap()
|
MemMap::~MemMap()
|
||||||
{
|
{
|
||||||
StdioFile::UnMap( m_addr, m_length ) ;
|
File::UnMap( m_addr, m_length ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* MemMap::Addr() const
|
void* MemMap::Addr() const
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
namespace gr {
|
namespace gr {
|
||||||
|
|
||||||
class StdioFile ;
|
class File ;
|
||||||
|
|
||||||
class MemMap
|
class MemMap
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,7 @@ public :
|
||||||
struct Error : virtual Exception {} ;
|
struct Error : virtual Exception {} ;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
MemMap( StdioFile& file, off_t offset, std::size_t length ) ;
|
MemMap( File& file, off_t offset, std::size_t length ) ;
|
||||||
~MemMap() ;
|
~MemMap() ;
|
||||||
|
|
||||||
void* Addr() const ;
|
void* Addr() const ;
|
||||||
|
|
Loading…
Reference in New Issue