src/Env/Param/ParamXMLPath.cpp

説明を見る。
00001 // 
00002 // Copyright (c) 2005-2008 Kenichi Watanabe.
00003 // Copyright (c) 2005-2008 Yasuhiro Watari.
00004 // Copyright (c) 2005-2008 Hironori Ichibayashi.
00005 // Copyright (c) 2008-2009 Kazuo Horio.
00006 // Copyright (c) 2009-2013 Naruki Kurata.
00007 // Copyright (c) 2005-2013 Ryota Shioya.
00008 // Copyright (c) 2005-2013 Masahiro Goshima.
00009 // 
00010 // This software is provided 'as-is', without any express or implied
00011 // warranty. In no event will the authors be held liable for any damages
00012 // arising from the use of this software.
00013 // 
00014 // Permission is granted to anyone to use this software for any purpose,
00015 // including commercial applications, and to alter it and redistribute it
00016 // freely, subject to the following restrictions:
00017 // 
00018 // 1. The origin of this software must not be misrepresented; you must not
00019 // claim that you wrote the original software. If you use this software
00020 // in a product, an acknowledgment in the product documentation would be
00021 // appreciated but is not required.
00022 // 
00023 // 2. Altered source versions must be plainly marked as such, and must not be
00024 // misrepresented as being the original software.
00025 // 
00026 // 3. This notice may not be removed or altered from any source
00027 // distribution.
00028 // 
00029 // 
00030 
00031 
00032 #include <pch.h>
00033 #include "Env/Param/ParamXMLPath.h"
00034 
00035 using namespace std;
00036 using namespace boost;
00037 using namespace Onikiri;
00038 
00039 ParamXMLPath::Node::Node()
00040 {
00041     type = NT_NORMAL;
00042     arrayIndex = 0;
00043 }
00044 
00045 ParamXMLPath::ParamXMLPath()
00046 {
00047 }
00048 
00049 ParamXMLPath::ParamXMLPath( const ParamXMLPath& org )
00050 {
00051     m_path = org.m_path;
00052 }
00053 
00054 ParamXMLPath::ParamXMLPath( const String& source )
00055 {
00056     Parse( m_path, source );
00057 }
00058 
00059 ParamXMLPath::ParamXMLPath( const std::string& source )
00060 {
00061     Parse( m_path, source );
00062 }
00063 
00064 ParamXMLPath::ParamXMLPath( const char* source )
00065 {
00066     Parse( m_path, source );
00067 }
00068 
00069 ParamXMLPath::~ParamXMLPath()
00070 {
00071 }
00072 
00073 
00074 ParamXMLPath::TokenList::const_iterator 
00075     ParamXMLPath::NextToken(
00076         const TokenList& tokens,
00077         TokenList::const_iterator cur,
00078         const String& source
00079 ){
00080     ++cur;
00081     if( cur == tokens.end() ){
00082         THROW_RUNTIME_ERROR( "'%s' is an invalid path format.", source.c_str() );
00083     }
00084     return cur;
00085 }
00086 
00087 // Parse the 'source' as XPath format.
00088 // Parsed results are added to the 'path'.
00089 void ParamXMLPath::Parse( Path& path, const String& source )
00090 {
00091     const vector<String>& tokens = source.split( "/", "[]@#()" );
00092     for( vector<String>::const_iterator i = tokens.begin();
00093          i != tokens.end();
00094          ++i
00095     ){
00096         NodePtr node( new Node );
00097         const String& token = *i;
00098 
00099         if( token == "@" ){
00100 
00101             // Attribute
00102             i = NextToken( tokens, i, source );
00103             node->type = NT_ATTRIBUTE;
00104             node->str = *i;
00105 
00106         }
00107         else if( token == "#" ){
00108             
00109             // Count function (abbreviation version)
00110             i = NextToken( tokens, i, source );
00111             node->type = NT_COUNT_FUNCTION;
00112             node->str = *i;
00113 
00114         }
00115         else{
00116 
00117             node->str = token;
00118             if( i+1 != tokens.end() ){
00119 
00120                 const String& next = *NextToken( tokens, i, source );
00121 
00122                 if( next == "[" ){
00123                     // Array
00124                     node->type = NT_ARRAY;
00125 
00126                     i = NextToken( tokens, i, source ); // i: '['
00127                     i = NextToken( tokens, i, source ); // i: '<number>'
00128                     node->arrayIndex = lexical_cast<int>(*i);
00129 
00130                     i = NextToken( tokens, i, source ); // i: ']'
00131                     if( *i != "]" ){
00132                         THROW_RUNTIME_ERROR( "'%s' has an invalid array format.", source.c_str() );
00133                     }
00134                 }
00135                 else if( next == "(" ){
00136 
00137                     // XPath functions or text()
00138                     const String& function = node->str;
00139 
00140                     if( function == "text" ){
00141 
00142                         // text() node.
00143                         node->type = NT_TEXT;
00144                         i = NextToken( tokens, i, source ); // i: '('
00145                         i = NextToken( tokens, i, source ); // i: ')'
00146                         if( *i != ")" ){
00147                             THROW_RUNTIME_ERROR( "'%s' has an invalid text format.", source.c_str() );
00148                         }
00149 
00150                     }
00151                     else if( function == "count" ){
00152                         
00153                         // Count function
00154                         node->type = NT_COUNT_FUNCTION;
00155 
00156                         i = NextToken( tokens, i, source ); // '('
00157                         i = NextToken( tokens, i, source ); // '<body>'
00158                         node->str = *i;
00159                         i = NextToken( tokens, i, source ); // ')'
00160                         if( *i != ")" ){
00161                             THROW_RUNTIME_ERROR( "'%s' has an invalid function format.", source.c_str() );
00162                         }
00163 
00164                     }
00165                     else{
00166                         THROW_RUNTIME_ERROR( "'%s' has an invalid path format.", source.c_str() );
00167                     }
00168 
00169                 }
00170                 else{
00171                     // Normal path
00172                 }
00173             }   //  if( i+1 != tokens.end() ){
00174             else{
00175                 // Normal path
00176             }
00177                 
00178         }   // if( *i == "@" ){
00179 
00180         // Add a parsed node.
00181         path.push_back( node );
00182 
00183     }   // for( vector<String>::const_iterator i = tokens.begin();
00184 }
00185 
00186 String ParamXMLPath::ToString() const
00187 {
00188     String ret;
00189     for( const_iterator i = begin(); i != end(); ++i ){
00190         ret += "/";
00191 
00192         const NodePtr& node = *i;
00193         switch( node->type ){
00194         case NT_ARRAY:
00195             ret += String().format( "%s[%d]", node->str.c_str(), node->arrayIndex );
00196             break;
00197         case NT_COUNT_FUNCTION:
00198             ret += String().format( "#%s", node->str.c_str() );
00199             break;
00200         case NT_ATTRIBUTE:
00201             ret += String().format( "@%s", node->str.c_str() );
00202             break;
00203         case NT_TEXT:
00204             ret += "text()";
00205             break;
00206         default:
00207             ret += node->str;
00208             break;
00209         }
00210     }
00211     return ret;
00212 }
00213 
00214 ParamXMLPath& ParamXMLPath::operator +=( const ParamXMLPath& rhs )
00215 {
00216     for( const_iterator i = rhs.begin(); i != rhs.end(); ++i ){
00217         m_path.push_back( *i );
00218     }
00219     return *this;
00220 }
00221 
00222 ParamXMLPath& ParamXMLPath::operator +=( const String& rhs )
00223 {
00224     Parse( m_path, rhs );
00225     return *this;
00226 }
00227 
00228 ParamXMLPath& ParamXMLPath::operator +=( const char* rhs )
00229 {
00230     Parse( m_path, rhs );
00231     return *this;
00232 }
00233 
00234 ParamXMLPath ParamXMLPath::operator +( const ParamXMLPath& rhs ) const
00235 {
00236     ParamXMLPath tmp = *this;
00237     tmp += rhs;
00238     return tmp;
00239 }
00240 
00241 ParamXMLPath ParamXMLPath::operator +( const String& rhs ) const
00242 {
00243     ParamXMLPath tmp = *this;
00244     tmp += rhs;
00245     return tmp;
00246 }
00247 
00248 ParamXMLPath ParamXMLPath::operator +( const char* rhs ) const
00249 {
00250     ParamXMLPath tmp = *this;
00251     tmp += rhs;
00252     return tmp;
00253 }
00254 
00255 ParamXMLPath& ParamXMLPath::operator = ( const String& rhs )
00256 {
00257     m_path.clear();
00258     Parse( m_path, rhs );
00259     return *this;
00260 }
00261 
00262 ParamXMLPath& ParamXMLPath::operator = ( const char* rhs )
00263 {
00264     m_path.clear();
00265     Parse( m_path, rhs );
00266     return *this;
00267 }
00268 
00269 ParamXMLPath::NodePtr& ParamXMLPath::Back()
00270 {
00271     return back();
00272 }
00273 
00274 const ParamXMLPath::NodePtr ParamXMLPath::Back() const
00275 {
00276     return back();
00277 }
00278 
00279 void ParamXMLPath::RemoveLast()
00280 {
00281     pop_back();
00282 }
00283 
00284 void ParamXMLPath::Add( const String& path )
00285 {
00286     Parse( m_path, path );
00287 }
00288 
00289 void ParamXMLPath::AddAttribute( const String& path )
00290 {
00291     NodePtr node( new Node );
00292     node->type = NT_ATTRIBUTE;
00293     node->str = path;
00294     m_path.push_back( node );
00295 }
00296 
00297 void ParamXMLPath::AddArray( const String& path, int index )
00298 {
00299     Parse( m_path, path );
00300     m_path.back()->type = NT_ARRAY;
00301     m_path.back()->arrayIndex = index;
00302 }
00303 
00304 void ParamXMLPath::SetArray( const ParamXMLPath& basePath, const String& relativePath, int index )
00305 {
00306     *this = basePath;
00307     AddArray( relativePath, index );
00308 }
00309 
00310 
00311 //
00312 // -- list compatible 
00313 //
00314 void ParamXMLPath::pop_back()
00315 {
00316     if( m_path.size() > 0 )
00317         m_path.pop_back();
00318 }
00319 
00320 ParamXMLPath::NodePtr& 
00321 ParamXMLPath::back()
00322 {
00323     return m_path.back();
00324 }
00325 
00326 const ParamXMLPath::NodePtr& 
00327 ParamXMLPath::back() const
00328 {
00329     return m_path.back();
00330 }
00331 
00332 ParamXMLPath::iterator ParamXMLPath::begin()
00333 {
00334     return m_path.begin();
00335 }
00336 
00337 ParamXMLPath::iterator ParamXMLPath::end()
00338 {
00339     return m_path.end();
00340 }
00341 
00342 ParamXMLPath::const_iterator ParamXMLPath::begin() const
00343 {
00344     return m_path.begin();
00345 }
00346 
00347 ParamXMLPath::const_iterator ParamXMLPath::end() const
00348 {
00349     return m_path.end();
00350 }

Onikiri2に対してTue Jun 18 14:34:20 2013に生成されました。  doxygen 1.4.7