Skip to content

Commit

Permalink
added ValResponse class to parse JSON from http
Browse files Browse the repository at this point in the history
  • Loading branch information
nestal committed May 1, 2013
1 parent 2d29692 commit abfa9ce
Show file tree
Hide file tree
Showing 13 changed files with 460 additions and 178 deletions.
1 change: 1 addition & 0 deletions libgrive/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ file (GLOB LIBGRIVE_SRC
src/drive2/*.cc
src/http/*.cc
src/protocol/*.cc
src/json/*.cc
src/util/*.cc
src/util/log/*.cc
src/xml/*.cc
Expand Down
135 changes: 0 additions & 135 deletions libgrive/src/drive2/JsonVal.cc

This file was deleted.

174 changes: 174 additions & 0 deletions libgrive/src/json/JsonParser.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/*
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 "JsonParser.hh"

#include "Val.hh"
#include "ValBuilder.hh"

#include <yajl/yajl_parse.h>

namespace gr {

namespace
{
int OnNull( void *ctx )
{
ValVisitor *b = reinterpret_cast<ValVisitor*>(ctx) ;
b->VisitNull() ;
return true ;
}

int OnBool( void *ctx, int value )
{
ValVisitor *b = reinterpret_cast<ValVisitor*>(ctx) ;
b->Visit( static_cast<long long>(value) ) ;
return true ;
}

int OnInt( void *ctx, long long value )
{
ValVisitor *b = reinterpret_cast<ValVisitor*>(ctx) ;
b->Visit(value) ;
return true ;
}

int OnDouble( void *ctx, double value )
{
ValVisitor *b = reinterpret_cast<ValVisitor*>(ctx) ;
b->Visit(value) ;
return true ;
}

int OnStr( void *ctx, const unsigned char *str, std::size_t len )
{
ValVisitor *b = reinterpret_cast<ValVisitor*>(ctx) ;
b->Visit( std::string(reinterpret_cast<const char*>(str), len) ) ;
return true ;
}

int StartMap( void *ctx )
{
ValVisitor *b = reinterpret_cast<ValVisitor*>(ctx) ;
b->StartObject() ;
return true ;
}

int OnMapKey( void *ctx, const unsigned char *str, std::size_t len )
{
ValVisitor *b = reinterpret_cast<ValVisitor*>(ctx) ;
b->VisitKey( std::string(reinterpret_cast<const char*>(str), len) ) ;
return true ;
}

int EndMap( void *ctx )
{
ValVisitor *b = reinterpret_cast<ValVisitor*>(ctx) ;
b->EndObject() ;
return true ;
}

int StartArray( void *ctx )
{
ValVisitor *b = reinterpret_cast<ValVisitor*>(ctx) ;
b->StartArray() ;
return true ;
}

int EndArray( void *ctx )
{
ValVisitor *b = reinterpret_cast<ValVisitor*>(ctx) ;
b->EndArray() ;
return true ;
}

const yajl_callbacks callbacks = {
OnNull,
OnBool,
OnInt,
OnDouble,
0,
OnStr,
StartMap,
OnMapKey,
EndMap,
StartArray,
EndArray,
};
}

void JsonParser::Parse( const std::string& json, ValVisitor *callback )
{
JsonParser parser( callback ) ;
parser.Parse( json.c_str(), json.size() ) ;
parser.Finish() ;
}

struct JsonParser::Impl
{
ValVisitor *callback ;
yajl_handle hand ;
} ;

JsonParser::JsonParser( ValVisitor *callback ) :
m_impl( new Impl )
{
m_impl->callback = callback ;
m_impl->hand = yajl_alloc( &callbacks, 0, m_impl->callback ) ;
}

JsonParser::~JsonParser()
{
yajl_free( m_impl->hand ) ;
}

void JsonParser::Parse( const char *str, std::size_t size )
{
const unsigned char *ustr = reinterpret_cast<unsigned const char*>(str) ;

yajl_status r = yajl_parse( m_impl->hand, ustr, size ) ;

if ( r != yajl_status_ok )
{
unsigned char *msg = yajl_get_error( m_impl->hand, true, ustr, size ) ;
std::string msg_str(reinterpret_cast<char*>(msg)) ;
yajl_free_error(m_impl->hand, msg) ;

BOOST_THROW_EXCEPTION(
Error()
<< ParseErr_(msg_str)
<< JsonText_(std::string(str,size))
);
}
}

void JsonParser::Finish()
{
if ( yajl_complete_parse(m_impl->hand) != yajl_status_ok )
{
unsigned char *msg = yajl_get_error( m_impl->hand, false, 0, 0 ) ;
std::string msg_str(reinterpret_cast<char*>(msg)) ;
yajl_free_error(m_impl->hand, msg) ;

BOOST_THROW_EXCEPTION( Error() << ParseErr_(msg_str) ) ;
}
}

} // end of namespace gr::json
53 changes: 53 additions & 0 deletions libgrive/src/json/JsonParser.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
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 "util/Exception.hh"

#include <string>
#include <memory>

namespace gr {

class ValVisitor ;

class JsonParser
{
public :
struct Error : virtual Exception {} ;
typedef boost::error_info<struct ParseErr, std::string> ParseErr_ ;
typedef boost::error_info<struct JsonText, std::string> JsonText_ ;

static void Parse( const std::string& json, ValVisitor *callback ) ;

explicit JsonParser( ValVisitor *callback ) ;
~JsonParser() ;

void Parse( const char *str, std::size_t size ) ;
void Finish() ;

private :
struct Impl ;
std::auto_ptr<Impl> m_impl ;
} ;

} // end of namespace

Loading

0 comments on commit abfa9ce

Please sign in to comment.