mirror of https://github.com/vitalif/grive2
adding xml tree basics
parent
7b8d22b2b7
commit
7d2b8b441d
|
@ -36,6 +36,7 @@ file (GLOB LIBGRIVE_SRC
|
||||||
src/drive/*.cc
|
src/drive/*.cc
|
||||||
src/protocol/*.cc
|
src/protocol/*.cc
|
||||||
src/util/*.cc
|
src/util/*.cc
|
||||||
|
src/xml/*.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library( grive SHARED ${LIBGRIVE_SRC} )
|
add_library( grive SHARED ${LIBGRIVE_SRC} )
|
||||||
|
@ -63,6 +64,7 @@ IF ( CPPUNIT_FOUND )
|
||||||
# list of test source files here
|
# list of test source files here
|
||||||
file(GLOB TEST_SRC
|
file(GLOB TEST_SRC
|
||||||
test/util/*.cc
|
test/util/*.cc
|
||||||
|
test/xml/*.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable( unittest
|
add_executable( unittest
|
||||||
|
|
|
@ -0,0 +1,212 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Node.hh"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <functional>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace gr { namespace xml {
|
||||||
|
|
||||||
|
class Node::Impl
|
||||||
|
{
|
||||||
|
private :
|
||||||
|
typedef std::vector<Impl*> ImplVec ;
|
||||||
|
|
||||||
|
public :
|
||||||
|
typedef ImplVec::iterator iterator ;
|
||||||
|
|
||||||
|
public :
|
||||||
|
Impl() : m_ref(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Impl( const std::string& str, Type type ) :
|
||||||
|
m_ref(1),
|
||||||
|
m_type( type ),
|
||||||
|
m_str( str )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~Impl()
|
||||||
|
{
|
||||||
|
std::for_each( m_children.begin(), m_children.end(), std::mem_fun( &Impl::Release ) ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Impl* AddRef()
|
||||||
|
{
|
||||||
|
++m_ref ;
|
||||||
|
return this ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Release()
|
||||||
|
{
|
||||||
|
if ( --m_ref == 0 )
|
||||||
|
delete this ;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t RefCount() const
|
||||||
|
{
|
||||||
|
assert( m_ref > 0 ) ;
|
||||||
|
return m_ref ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add( Impl *child )
|
||||||
|
{
|
||||||
|
assert( child != 0 ) ;
|
||||||
|
|
||||||
|
if ( child->m_type != text )
|
||||||
|
m_map.insert( std::lower_bound( m_map.begin(), m_map.end(), child, Comp() ), child ) ;
|
||||||
|
|
||||||
|
m_children.push_back( child ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Impl* Find( const std::string& str )
|
||||||
|
{
|
||||||
|
Impl tmp( str, element ) ;
|
||||||
|
iterator i = std::lower_bound( m_map.begin(), m_map.end(), &tmp, Comp() ) ;
|
||||||
|
return i != m_map.end() && (*i)->m_str == str ? *i : 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator Begin()
|
||||||
|
{
|
||||||
|
return m_children.begin() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator End()
|
||||||
|
{
|
||||||
|
return m_children.end() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& Str() const
|
||||||
|
{
|
||||||
|
return m_str ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Str( const std::string& str )
|
||||||
|
{
|
||||||
|
m_str = str ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type GetType() const
|
||||||
|
{
|
||||||
|
return m_type ;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Comp
|
||||||
|
{
|
||||||
|
bool operator()( Impl *p1, Impl *p2 ) const
|
||||||
|
{
|
||||||
|
return p1->Str() < p2->Str() ;
|
||||||
|
}
|
||||||
|
} ;
|
||||||
|
|
||||||
|
private :
|
||||||
|
std::size_t m_ref ;
|
||||||
|
|
||||||
|
Type m_type ;
|
||||||
|
std::string m_str ;
|
||||||
|
ImplVec m_map ;
|
||||||
|
ImplVec m_children ;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
Node::Node() : m_ptr( new Impl )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::Node( const Node& node ) : m_ptr( node.m_ptr->AddRef() )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::Node( Impl *impl ) : m_ptr( impl )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Node Node::Element( const std::string& name )
|
||||||
|
{
|
||||||
|
return Node( new Impl( name, element ) ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node Node::Text( const std::string& name )
|
||||||
|
{
|
||||||
|
return Node( new Impl( name, text ) ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::~Node()
|
||||||
|
{
|
||||||
|
assert( m_ptr != 0 ) ;
|
||||||
|
m_ptr->Release() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node& Node::operator=( const Node& node )
|
||||||
|
{
|
||||||
|
Node tmp( node ) ;
|
||||||
|
std::swap( tmp.m_ptr, m_ptr ) ;
|
||||||
|
return *this ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node Node::AddElement( const std::string& name )
|
||||||
|
{
|
||||||
|
assert( m_ptr != 0 ) ;
|
||||||
|
|
||||||
|
Impl *child = new Impl( name, element ) ;
|
||||||
|
m_ptr->Add( child->AddRef() ) ;
|
||||||
|
return Node( child ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node Node::AddText( const std::string& str )
|
||||||
|
{
|
||||||
|
assert( m_ptr != 0 ) ;
|
||||||
|
|
||||||
|
Impl *child = new Impl( str, text ) ;
|
||||||
|
m_ptr->Add( child->AddRef() ) ;
|
||||||
|
return Node( child ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node Node::operator[]( const std::string& name ) const
|
||||||
|
{
|
||||||
|
assert( m_ptr != 0 ) ;
|
||||||
|
Impl *i = m_ptr->Find( name ) ;
|
||||||
|
if ( i != 0 )
|
||||||
|
return Node( i->AddRef() ) ;
|
||||||
|
|
||||||
|
throw std::runtime_error( "node " + name + " can't be found" ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t Node::RefCount() const
|
||||||
|
{
|
||||||
|
assert( m_ptr != 0 ) ;
|
||||||
|
return m_ptr->RefCount() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::Type Node::GetType() const
|
||||||
|
{
|
||||||
|
assert( m_ptr != 0 ) ;
|
||||||
|
return m_ptr->GetType() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& Node::Str() const
|
||||||
|
{
|
||||||
|
assert( m_ptr != 0 ) ;
|
||||||
|
return m_ptr->Str() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
} } // end namespace
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
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 <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace gr { namespace xml {
|
||||||
|
|
||||||
|
class Node
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
Node() ;
|
||||||
|
Node( const Node& node ) ;
|
||||||
|
~Node() ;
|
||||||
|
|
||||||
|
static Node Element( const std::string& name ) ;
|
||||||
|
static Node Text( const std::string& name ) ;
|
||||||
|
|
||||||
|
Node& operator=( const Node& node ) ;
|
||||||
|
|
||||||
|
Node AddElement( const std::string& name ) ;
|
||||||
|
Node AddText( const std::string& text ) ;
|
||||||
|
|
||||||
|
Node operator[]( const std::string& name ) const ;
|
||||||
|
const std::string& Str() const ;
|
||||||
|
|
||||||
|
// read-only access to the reference counter. for checking.
|
||||||
|
std::size_t RefCount() const ;
|
||||||
|
|
||||||
|
enum Type { element, attr, text } ;
|
||||||
|
Type GetType() const ;
|
||||||
|
|
||||||
|
private :
|
||||||
|
class Impl ;
|
||||||
|
|
||||||
|
private :
|
||||||
|
explicit Node( Impl *impl ) ;
|
||||||
|
|
||||||
|
private :
|
||||||
|
Impl *m_ptr ;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
} } // end of namespace
|
|
@ -23,6 +23,7 @@
|
||||||
#include "util/FunctionTest.hh"
|
#include "util/FunctionTest.hh"
|
||||||
#include "util/PathTest.hh"
|
#include "util/PathTest.hh"
|
||||||
#include "util/SignalHandlerTest.hh"
|
#include "util/SignalHandlerTest.hh"
|
||||||
|
#include "xml/NodeTest.hh"
|
||||||
|
|
||||||
int main( int argc, char **argv )
|
int main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
|
@ -33,6 +34,7 @@ int main( int argc, char **argv )
|
||||||
runner.addTest( FunctionTest::suite( ) ) ;
|
runner.addTest( FunctionTest::suite( ) ) ;
|
||||||
runner.addTest( PathTest::suite( ) ) ;
|
runner.addTest( PathTest::suite( ) ) ;
|
||||||
runner.addTest( SignalHandlerTest::suite( ) ) ;
|
runner.addTest( SignalHandlerTest::suite( ) ) ;
|
||||||
|
runner.addTest( NodeTest::suite( ) ) ;
|
||||||
runner.run();
|
runner.run();
|
||||||
|
|
||||||
return 0 ;
|
return 0 ;
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "NodeTest.hh"
|
||||||
|
|
||||||
|
#include "xml/Node.hh"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace grut {
|
||||||
|
|
||||||
|
using namespace gr::xml ;
|
||||||
|
|
||||||
|
NodeTest::NodeTest( )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeTest::TestTree( )
|
||||||
|
{
|
||||||
|
Node node = Node::Element( "root" ) ;
|
||||||
|
CPPUNIT_ASSERT_EQUAL( 1UL, node.RefCount() ) ;
|
||||||
|
CPPUNIT_ASSERT_EQUAL( Node::element, node.GetType() ) ;
|
||||||
|
|
||||||
|
Node c1 = node.AddElement( "child1" ) ;
|
||||||
|
c1.AddText( "this is a line" ) ;
|
||||||
|
Node c11 = c1.AddElement( "b" ) ;
|
||||||
|
CPPUNIT_ASSERT_EQUAL( 2UL, c1.RefCount() ) ;
|
||||||
|
|
||||||
|
Node c2 = node.AddElement( "child2" ) ;
|
||||||
|
Node c0 = node.AddElement( "child0" ) ;
|
||||||
|
|
||||||
|
Node c1_ = node["child1"] ;
|
||||||
|
Node c11_ = node["child1"]["b"] ;
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL( 3UL, c1_.RefCount() ) ;
|
||||||
|
CPPUNIT_ASSERT_EQUAL( std::string("child1"), c1_.Str() ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of namespace grut
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
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 <cppunit/TestFixture.h>
|
||||||
|
#include <cppunit/extensions/HelperMacros.h>
|
||||||
|
|
||||||
|
namespace grut {
|
||||||
|
|
||||||
|
class NodeTest : public CppUnit::TestFixture
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
NodeTest( ) ;
|
||||||
|
|
||||||
|
// declare suit function
|
||||||
|
CPPUNIT_TEST_SUITE( NodeTest ) ;
|
||||||
|
CPPUNIT_TEST( TestTree ) ;
|
||||||
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
|
private :
|
||||||
|
void TestTree( ) ;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
} // end of namespace
|
Loading…
Reference in New Issue