00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00088
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
00102 i = NextToken( tokens, i, source );
00103 node->type = NT_ATTRIBUTE;
00104 node->str = *i;
00105
00106 }
00107 else if( token == "#" ){
00108
00109
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
00124 node->type = NT_ARRAY;
00125
00126 i = NextToken( tokens, i, source );
00127 i = NextToken( tokens, i, source );
00128 node->arrayIndex = lexical_cast<int>(*i);
00129
00130 i = NextToken( tokens, i, source );
00131 if( *i != "]" ){
00132 THROW_RUNTIME_ERROR( "'%s' has an invalid array format.", source.c_str() );
00133 }
00134 }
00135 else if( next == "(" ){
00136
00137
00138 const String& function = node->str;
00139
00140 if( function == "text" ){
00141
00142
00143 node->type = NT_TEXT;
00144 i = NextToken( tokens, i, source );
00145 i = NextToken( tokens, i, source );
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
00154 node->type = NT_COUNT_FUNCTION;
00155
00156 i = NextToken( tokens, i, source );
00157 i = NextToken( tokens, i, source );
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
00172 }
00173 }
00174 else{
00175
00176 }
00177
00178 }
00179
00180
00181 path.push_back( node );
00182
00183 }
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
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 }