Permalink
Browse files

added yajl parser

  • Loading branch information...
1 parent 540e3d8 commit 2d29692601c653591632b256c5822fa39a0ca9c0 @nestal nestal committed May 1, 2013
View
@@ -79,6 +79,7 @@ add_definitions(
add_library( grive STATIC ${LIBGRIVE_SRC} ${OPT_SRC} )
target_link_libraries( grive
+ yajl
${CURL_LIBRARIES}
${JSONC_LIBRARY}
${LIBGCRYPT_LIBRARIES}
@@ -132,9 +133,11 @@ IF ( CPPUNIT_FOUND )
ENDIF ( CPPUNIT_FOUND )
-add_executable( btest
- test/btest/ValTest.cc
- test/btest/UnitTest.cc )
+file(GLOB BTEST_SRC
+ test/btest/*.cc
+)
+
+add_executable( btest ${BTEST_SRC} )
target_link_libraries( btest
grive
@@ -0,0 +1,135 @@
+/*
+ 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 "JsonVal.hh"
+
+#include "Val.hh"
+#include "ValBuilder.hh"
+
+#include <yajl/yajl_parse.h>
+
+namespace gr { namespace json {
+
+namespace
+{
+ int OnNull( void *ctx )
+ {
+ ValBuilder *b = reinterpret_cast<ValBuilder*>(ctx) ;
+ b->BuildNull() ;
+ return true ;
+ }
+
+ int OnBool( void *ctx, int value )
+ {
+ ValBuilder *b = reinterpret_cast<ValBuilder*>(ctx) ;
+ b->Build( static_cast<long long>(value) ) ;
+ return true ;
+ }
+
+ int OnInt( void *ctx, long long value )
+ {
+ ValBuilder *b = reinterpret_cast<ValBuilder*>(ctx) ;
+ b->Build(value) ;
+ return true ;
+ }
+
+ int OnDouble( void *ctx, double value )
+ {
+ ValBuilder *b = reinterpret_cast<ValBuilder*>(ctx) ;
+ b->Build(value) ;
+ return true ;
+ }
+
+ int OnStr( void *ctx, const unsigned char *str, std::size_t len )
+ {
+ ValBuilder *b = reinterpret_cast<ValBuilder*>(ctx) ;
+ b->Build( std::string(reinterpret_cast<const char*>(str), len) ) ;
+ return true ;
+ }
+
+ int StartMap( void *ctx )
+ {
+ ValBuilder *b = reinterpret_cast<ValBuilder*>(ctx) ;
+ b->StartObject() ;
+ return true ;
+ }
+
+ int OnMapKey( void *ctx, const unsigned char *str, std::size_t len )
+ {
+ ValBuilder *b = reinterpret_cast<ValBuilder*>(ctx) ;
+ b->BuildKey( std::string(reinterpret_cast<const char*>(str), len) ) ;
+ return true ;
+ }
+
+ int EndMap( void *ctx )
+ {
+ ValBuilder *b = reinterpret_cast<ValBuilder*>(ctx) ;
+ b->EndObject() ;
+ return true ;
+ }
+
+ int StartArray( void *ctx )
+ {
+ ValBuilder *b = reinterpret_cast<ValBuilder*>(ctx) ;
+ b->StartArray() ;
+ return true ;
+ }
+
+ int EndArray( void *ctx )
+ {
+ ValBuilder *b = reinterpret_cast<ValBuilder*>(ctx) ;
+ b->EndArray() ;
+ return true ;
+ }
+
+ const yajl_callbacks callbacks = {
+ OnNull,
+ OnBool,
+ OnInt,
+ OnDouble,
+ 0,
+ OnStr,
+ StartMap,
+ OnMapKey,
+ EndMap,
+ StartArray,
+ EndArray,
+ };
+}
+
+Val Parse( const std::string& json )
+{
+ ValBuilder b ;
+ yajl_handle hand = yajl_alloc( &callbacks, 0, &b ) ;
+ yajl_parse( hand, reinterpret_cast<unsigned const char*>(json.c_str()), json.size() ) ;
+
+ if ( yajl_complete_parse(hand) != yajl_status_ok )
+ {
+ unsigned char *msg = yajl_get_error( hand, true, reinterpret_cast<unsigned const char*>(json.c_str()), json.size() ) ;
+ std::string msg_str(reinterpret_cast<char*>(msg)) ;
+ yajl_free_error(hand, msg) ;
+
+ BOOST_THROW_EXCEPTION( Error() << ParseErr_(msg_str) << JsonText_(json) ) ;
+ }
+
+ return b.Result() ;
+}
+
+} } // end of namespace gr::json
@@ -0,0 +1,41 @@
+/*
+ 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>
+
+namespace gr
+{
+ class Val ;
+
+ namespace json
+ {
+ struct Error : virtual Exception {} ;
+ typedef boost::error_info<struct ParseErr, std::string> ParseErr_ ;
+ typedef boost::error_info<struct JsonText, std::string> JsonText_ ;
+
+ Val Parse( const std::string& json ) ;
+ }
+
+} // end of namespace
+
View
@@ -106,16 +106,6 @@ private :
std::auto_ptr<Base> m_base ;
private :
- // callback functions
- static int OnNull( void *ctx ) ;
- static int OnBool( void *ctx, int value ) ;
- static int OnInt( void *ctx, long long value ) ;
- static int OnDouble( void *ctx, double value ) ;
- static int OnStr( void *ctx, const unsigned char *str, std::size_t len ) ;
- static int StartMap( void *ctx ) ;
- static int EndMap( void *ctx ) ;
- static int StartArray( void *ctx ) ;
- static int EndArray( void *ctx ) ;
} ;
template <> struct Val::Type2Enum<void> { static const TypeEnum type = null_type ; } ;
@@ -132,6 +122,8 @@ template <> struct Val::SupportType<long> { typedef long long Type ; } ;
template <> struct Val::SupportType<unsigned long> { typedef long long Type ; } ;
template <> struct Val::SupportType<short> { typedef long long Type ; } ;
template <> struct Val::SupportType<unsigned short> { typedef long long Type ; } ;
+template <> struct Val::SupportType<long long> { typedef long long Type ; } ;
+template <> struct Val::SupportType<unsigned long long> { typedef long long Type ; } ;
template <> struct Val::SupportType<bool> { typedef bool Type ; } ;
template <> struct Val::SupportType<double> { typedef double Type ; } ;
@@ -0,0 +1,130 @@
+/*
+ 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 "ValBuilder.hh"
+
+#include <cassert>
+
+namespace gr {
+
+ValBuilder::ValBuilder( )
+{
+}
+
+ValBuilder::~ValBuilder()
+{
+}
+
+void ValBuilder::Build( long long t )
+{
+ Build(Val(t)) ;
+}
+
+void ValBuilder::Build( double t )
+{
+ Build(Val(t)) ;
+}
+
+void ValBuilder::Build( const std::string& t )
+{
+ Build(Val(t)) ;
+}
+
+void ValBuilder::Build( bool t )
+{
+ Build(Val(t)) ;
+}
+
+void ValBuilder::BuildNull()
+{
+ Build(Val()) ;
+}
+
+void ValBuilder::Build( const Val& t )
+{
+ if ( m_ctx.empty() )
+ m_ctx.push( t ) ;
+
+ else if ( m_ctx.top().Is<Val::Array>() )
+ {
+ Val::Array& ar = m_ctx.top().As<Val::Array>() ;
+ ar.push_back( t ) ;
+ }
+ else if ( m_ctx.top().Is<Val::Object>() )
+ {
+ if ( m_key.get() == 0 )
+ BOOST_THROW_EXCEPTION( Error() << NoKey_(t) ) ;
+
+ else
+ {
+ Val::Object& obj = m_ctx.top().As<Val::Object>() ;
+ obj.insert( std::make_pair( m_key->As<std::string>(), t ) ) ;
+ m_key.reset() ;
+ }
+ }
+ else
+ BOOST_THROW_EXCEPTION( Error() << Unexpected_(m_ctx.top()) ) ;
+}
+
+void ValBuilder::BuildKey( const std::string& t )
+{
+ m_key.reset( new Val(t) ) ;
+}
+
+void ValBuilder::StartArray()
+{
+ m_ctx.push( Val( Val::Array() ) ) ;
+}
+
+void ValBuilder::EndArray()
+{
+ End( Val::array_type ) ;
+}
+
+void ValBuilder::End( Val::TypeEnum type )
+{
+ if ( m_ctx.top().Type() == type )
+ {
+ // get top Val from stack
+ Val current ;
+ current.Swap( m_ctx.top() ) ;
+ m_ctx.pop() ;
+
+ Build(current) ;
+ }
+}
+
+void ValBuilder::StartObject()
+{
+ m_ctx.push( Val( Val::Object() ) ) ;
+}
+
+void ValBuilder::EndObject()
+{
+ End( Val::object_type ) ;
+}
+
+Val ValBuilder::Result() const
+{
+ assert( m_ctx.size() == 1U ) ;
+ return m_ctx.top() ;
+}
+
+} // end of namespace
Oops, something went wrong.

0 comments on commit 2d29692

Please sign in to comment.