Permalink
Browse files

added json writer

  • Loading branch information...
1 parent abfa9ce commit 6fa6e690c6d27ad21bc008ed966616485269dd11 @nestal nestal committed May 1, 2013
@@ -19,6 +19,7 @@
*/
#include "Val.hh"
+#include "ValVisitor.hh"
#include <iostream>
@@ -132,6 +133,45 @@ void Val::Add( const std::string& key, const Val& value )
As<Object>().insert( std::make_pair(key, value) ) ;
}
+void Val::Visit( ValVisitor *visitor ) const
+{
+ switch ( Type() )
+ {
+ case null_type: visitor->VisitNull() ; break ;
+ case int_type: visitor->Visit( As<long long>() ) ; break ;
+ case double_type: visitor->Visit( As<double>() ) ; break ;
+ case string_type: visitor->Visit( As<std::string>() ) ; break ;
+ case bool_type: visitor->Visit( As<bool>() ) ; break ;
+
+ case object_type:
+ {
+ visitor->StartObject() ;
+
+ const Object& obj = As<Object>() ;
+ for ( Object::const_iterator i = obj.begin() ; i != obj.end() ; ++i )
+ {
+ visitor->VisitKey( i->first ) ;
+ i->second.Visit( visitor ) ;
+ }
+
+ visitor->EndObject() ;
+ break ;
+ }
+
+ case array_type:
+ {
+ visitor->StartArray() ;
+
+ const Array& arr = As<Array>() ;
+ for ( Array::const_iterator i = arr.begin() ; i != arr.end() ; ++i )
+ i->Visit( visitor ) ;
+
+ visitor->EndArray() ;
+ break ;
+ }
+ }
+}
+
} // end of namespace
namespace std
@@ -112,7 +112,7 @@ public :
bool FindInArray( const std::string& key, const std::string& value, Val& result ) const ;
// friend std::ostream& operator<<( std::ostream& os, const Val& json ) ;
-// void Visit( DataStream *out ) const ;
+ void Visit( ValVisitor *visitor ) const ;
private :
struct Base ;
@@ -0,0 +1,111 @@
+/*
+ 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 "ValWriter.hh"
+#include "util/DataStream.hh"
+
+#include <yajl/yajl_gen.h>
+
+#include <cassert>
+
+namespace gr {
+
+struct ValWriter::Impl
+{
+ yajl_gen gen ;
+ DataStream *out ;
+} ;
+
+ValWriter::ValWriter( DataStream *out ) :
+ m_impl( new Impl )
+{
+ assert( out != 0 ) ;
+
+ m_impl->out = out ;
+ m_impl->gen = yajl_gen_alloc(0) ;
+ yajl_gen_config( m_impl->gen, yajl_gen_print_callback, &ValWriter::WriteCallback, this ) ;
+}
+
+ValWriter::~ValWriter()
+{
+ yajl_gen_free( m_impl->gen ) ;
+}
+
+void ValWriter::Visit( long long t )
+{
+ yajl_gen_integer( m_impl->gen, t ) ;
+}
+
+void ValWriter::Visit( double t )
+{
+ yajl_gen_double( m_impl->gen, t ) ;
+}
+
+void ValWriter::Visit( const std::string& t )
+{
+ yajl_gen_string( m_impl->gen,
+ reinterpret_cast<const unsigned char*>(t.c_str()), t.size() ) ;
+}
+
+void ValWriter::Visit( bool t )
+{
+ yajl_gen_bool( m_impl->gen, t ) ;
+}
+
+void ValWriter::VisitNull()
+{
+ yajl_gen_null( m_impl->gen ) ;
+}
+
+void ValWriter::StartArray()
+{
+ yajl_gen_array_open( m_impl->gen ) ;
+}
+
+void ValWriter::EndArray()
+{
+ yajl_gen_array_close( m_impl->gen ) ;
+}
+
+void ValWriter::StartObject()
+{
+ yajl_gen_map_open( m_impl->gen ) ;
+}
+
+void ValWriter::VisitKey( const std::string& t )
+{
+ Visit(t) ;
+}
+
+void ValWriter::EndObject()
+{
+ yajl_gen_map_close( m_impl->gen ) ;
+}
+
+void ValWriter::WriteCallback( void *ctx, const char *str, std::size_t size )
+{
+ ValWriter *pthis = reinterpret_cast<ValWriter*>(ctx) ;
+ assert( pthis != 0 ) ;
+ assert( pthis->m_impl->out != 0 ) ;
+
+ pthis->m_impl->out->Write( str, size ) ;
+}
+
+} // end of namespace
@@ -0,0 +1,57 @@
+/*
+ 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 "ValVisitor.hh"
+#include <memory>
+
+namespace gr {
+
+class DataStream ;
+
+class ValWriter : public ValVisitor
+{
+public :
+ ValWriter( DataStream *out ) ;
+ ~ValWriter() ;
+
+ void Visit( long long t ) ;
+ void Visit( double t ) ;
+ void Visit( const std::string& t ) ;
+ void Visit( bool t ) ;
+ void VisitNull() ;
+
+ void StartArray() ;
+ void EndArray() ;
+ void StartObject() ;
+ void VisitKey( const std::string& t ) ;
+ void EndObject() ;
+
+private :
+ static void WriteCallback( void *ctx, const char *str, std::size_t size ) ;
+
+private :
+ struct Impl ;
+ std::auto_ptr<Impl> m_impl ;
+} ;
+
+} // end of namespace
+
@@ -0,0 +1,67 @@
+/*
+ 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.
+*/
+
+#include "StringStream.hh"
+
+#include <algorithm>
+
+namespace gr {
+
+namespace
+{
+ // the max size of the cached string. this is to prevent allocating
+ // too much memory if client sends a line too long (i.e. DOS attack)
+ const std::size_t capacity = 1024 ;
+}
+
+StringStream::StringStream( const std::string& init ) :
+ m_str( init )
+{
+}
+
+/// Read `size` bytes from the stream. Those bytes will be removed from
+/// the underlying string by calling `std::string::erase()`. Therefore, it is
+/// not a good idea to call Read() to read byte-by-byte.
+std::size_t StringStream::Read( char *data, std::size_t size )
+{
+ // wow! no need to count count == 0
+ std::size_t count = std::min( m_str.size(), size ) ;
+ std::copy( m_str.begin(), m_str.begin() + count, data ) ;
+ m_str.erase( 0, count ) ;
+ return count ;
+}
+
+std::size_t StringStream::Write( const char *data, std::size_t size )
+{
+ std::size_t count = std::min( size, capacity - m_str.size() ) ;
+ m_str.insert( m_str.end(), data, data+count ) ;
+ return count ;
+}
+
+const std::string& StringStream::Str() const
+{
+ return m_str ;
+}
+
+void StringStream::Str( const std::string& str )
+{
+ m_str = str ;
+}
+
+} // end of namespace
@@ -0,0 +1,56 @@
+/*
+ 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 "DataStream.hh"
+
+#include <string>
+
+namespace gr {
+
+/** \brief DataStream base on `std::string`s
+
+ StringStream is a DataStream back-end that uses std::string for storage.
+ It is useful for unit tests and text parsing, especially when used with
+ StreamParser.
+
+ StringStream has a limit on the maximum number of byte it stores. This
+ is to prevent DOS attacks in which the client sends a lot of bytes before
+ the delimiter (e.g. new-line characters) and the server is forced to hold
+ all of them in memory.
+
+ The limit is current 1024 bytes.
+*/
+class StringStream : public DataStream
+{
+public :
+ explicit StringStream( const std::string& init = std::string() ) ;
+
+ std::size_t Read( char *data, std::size_t size ) ;
+ std::size_t Write( const char *data, std::size_t size ) ;
+
+ const std::string& Str() const ;
+ void Str( const std::string& str ) ;
+
+private :
+ std::string m_str ;
+} ;
+
+} // end of namespace
@@ -20,6 +20,8 @@
#include "json/JsonParser.hh"
#include "json/Val.hh"
#include "json/ValBuilder.hh"
+#include "json/ValWriter.hh"
+#include "util/StringStream.hh"
#include <boost/test/unit_test.hpp>
@@ -42,6 +44,14 @@ BOOST_AUTO_TEST_CASE( Test )
BOOST_CHECK( json.Is<Val::Object>() ) ;
BOOST_CHECK_EQUAL( json["key"].As<long long>(), 100 ) ;
+
+ StringStream ss ;
+ ValWriter wr( &ss ) ;
+ json.Visit( &wr ) ;
+
+ BOOST_CHECK_EQUAL( ss.Str(), "{\"key\":100}" ) ;
+
+// std::cout << ss.Str() << std::endl ;
}
BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 6fa6e69

Please sign in to comment.