src/Env/Param/ParamXMLTree.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/ParamXMLTree.h"
00034 #include "Env/Param/ParamXMLPrinter.h"
00035 
00036 using namespace std;
00037 using namespace boost;
00038 using namespace Onikiri;
00039 
00040 // A hash function for 'String'
00041 size_t ParamXMLTree::StringHash::operator()(const String& value) const
00042 {
00043     if( value.size() < 3 ){
00044         return 0;
00045     }
00046     else{
00047         return 
00048             ((value.at(0) << 8) | value.at(1)) ^
00049             value.at(2);
00050     }
00051 }
00052 
00053 ParamXMLTree::Node::Node()
00054 {
00055     status.stArray          = false;
00056     status.stReadOnly       = true;
00057     status.stRequireDefault = true;
00058     status.stDefault        = true;
00059     status.stAttribute      = false;
00060     inputIndex = -1;
00061     accessed = false;
00062 }
00063 
00064 ParamXMLTree::ParamXMLTree()
00065 {
00066     m_root = NodePtr( new Node() );
00067 
00068     // Default status
00069     m_root->name = "root";
00070 }
00071 
00072 ParamXMLTree::~ParamXMLTree()
00073 {
00074 }
00075 
00076 ParamXMLTree::NodePtr ParamXMLTree::CreateNewNode( const String& name )
00077 {
00078     Node* node = new Node();
00079     node->name = name;
00080     return NodePtr( node );
00081 }
00082 
00083 // Check parse error.
00084 void ParamXMLTree::CheckXMLParseError( TiXmlDocument& doc, const String& from )
00085 {
00086     if( doc.Error() ){
00087         String err;
00088         err.format(
00089             "Could not load from '%s'\n%s\nline:%d col:%d\n",
00090             from.c_str(),
00091             doc.ErrorDesc(),
00092             doc.ErrorRow(),
00093             doc.ErrorCol()
00094         );
00095         THROW_RUNTIME_ERROR( err.c_str() );
00096     }
00097 }
00098 
00099 // Copy node contents (attributes/nodes) from the 'src' to the 'dst'.
00100 void ParamXMLTree::CopyTree( NodePtr dst, NodePtr src )
00101 {
00102     dst->inputIndex = src->inputIndex;
00103     dst->status = src->status;
00104     dst->value = src->value;
00105     dst->name = src->name;
00106 
00107     // Copy attributes
00108     for( AttributeMap::iterator i = src->attributes.begin();
00109         i != src->attributes.end();
00110         ++i
00111     ){
00112         NodePtr newNode( new Node );
00113         *newNode = *i->second;
00114         dst->attributes[ i->first ] = newNode;
00115     }
00116 
00117     // Copy children
00118     for( ChildMap::iterator i = src->children.begin();
00119         i != src->children.end();
00120         ++i
00121     ){
00122         const String& name = i->first;
00123         NodeArray& children = i->second;
00124         for( size_t index = 0; index < children.size(); index++ ){
00125             NodePtr newNode( new Node );
00126             dst->children[ name ].push_back(newNode);
00127             CopyTree( newNode, children[ index ] );
00128         }
00129     }
00130 
00131     // Copy array placeholder
00132     for( ArrayPlaceMap::iterator i = src->arrayPlace.begin();
00133         i != src->arrayPlace.end();
00134         ++i
00135     ){
00136         NodePtr newNode( new Node );
00137         CopyTree( newNode, i->second );
00138         dst->arrayPlace[ i->first ] = newNode;
00139     }
00140 }
00141 
00142 
00143 // Convert each Tiny XML node to an internal map node recursively.
00144 void ParamXMLTree::ConvertXMLToMap( 
00145     NodePtr mapParent, TiXmlNode* xmlParent, int inputIndex, bool stDefault )
00146 {
00147     map<String, size_t> nodeCount;
00148     
00149     for( TiXmlElement* childElement = xmlParent->FirstChildElement();
00150          childElement != NULL;
00151          childElement = childElement->NextSiblingElement()
00152      ){
00153         
00154         NodePtr childNode( new Node() );
00155 
00156         // The status of a parent node is propagated to a child.
00157         const char* childName = childElement->Value();
00158         childNode->name = childName;
00159         childNode->status = mapParent->status;
00160         childNode->status.stDefault = stDefault;
00161         childNode->inputIndex = inputIndex;
00162         
00163         // Is a child node is a placeholder of an array?
00164         const char* pdbArrayStr = childElement->Attribute( "PDB_Array" );
00165         bool arrayPlace = pdbArrayStr ? lexical_cast<bool>(pdbArrayStr) : false;
00166 
00167         // Is a child node is a part of an array?
00168         bool arrayNode = 
00169             mapParent->arrayPlace.find( childName ) != mapParent->arrayPlace.end();
00170 
00171         // Convert an element
00172         if( arrayPlace ){
00173             // A node is a placeholder of 'array' (@PDB_Array='1'), 
00174             mapParent->arrayPlace[ childName ] = childNode;
00175         }
00176         else if( arrayNode ){
00177             // A node is 'array' (@PDB_Array='1'), 
00178             CopyTree( childNode, mapParent->arrayPlace[ childName ] );
00179             mapParent->children[ childName ].push_back( childNode );
00180             childNode->status.stArray = true;
00181         }
00182         else{
00183             // If a node is not 'array' (@PDB_Array='0'), already loaded nodes are over written.
00184             size_t index = nodeCount[ childName ];
00185             NodeArray& list = mapParent->children[ childName ];
00186             if( index >= list.size() ){
00187                 // Add a new node
00188                 list.resize( index + 1 );
00189                 list[index] = childNode;
00190             }
00191             else{
00192                 // An already loaded node is over written.
00193                 NodeStatus newStatus = childNode->status;
00194 
00195                 if(list[index]->status.stDefault){
00196                     // You cannot overwrite status 'stDefault'.
00197                     // If an old node is a 'default' node, 
00198                     // a new node is also 'default' node.
00199                     newStatus.stDefault = true;
00200                 }
00201 
00202                 childNode = list[index];
00203                 childNode->status = newStatus;
00204             }
00205 
00206             nodeCount[ childName ]++;
00207         }
00208         
00209         // Convert attributes
00210         for( TiXmlAttribute* attr = childElement->FirstAttribute();
00211              attr != NULL;
00212              attr = attr->Next() 
00213         ){
00214             const String& name  = attr->Name();
00215             const String& value = attr->Value();
00216             NodePtr attribute( new Node() );
00217             attribute->name  = name;
00218             attribute->value = value;
00219             attribute->inputIndex = inputIndex;
00220             childNode->attributes[ name ] = attribute;
00221 
00222             // Special internal attributes
00223             if( name == "PDB_Array" ){
00224                 arrayPlace = lexical_cast<bool>(value);
00225                 childNode->status.stArray = arrayPlace;
00226                 attribute->accessed = true;
00227             }
00228             else if( name == "PDB_ReadOnly" ){
00229                 childNode->status.stReadOnly = lexical_cast<bool>(value);
00230                 attribute->accessed = true;
00231             }
00232             else if( name == "PDB_RequireDefaultParam" ){
00233                 childNode->status.stRequireDefault = lexical_cast<bool>(value);
00234                 attribute->accessed = true;
00235             }
00236         }
00237 
00238         // Convert child nodes
00239         ConvertXMLToMap( childNode, childElement, inputIndex, stDefault );
00240     }
00241 }
00242 
00243 // Convert each internal map node to a tiny XML node recursively.
00244 void ParamXMLTree::ConvertMapToXML( TiXmlNode* xmlParent, NodePtr mapParent )
00245 {
00246 
00247     for( ChildMap::iterator children = mapParent->children.begin();
00248          children != mapParent->children.end();
00249          ++children
00250      ){
00251          
00252          // Get siblings, which are elements with same names.
00253          NodeArray& siblingList = children->second;
00254          for( size_t index = 0; index < siblingList.size(); index++ ){
00255 
00256             NodePtr sibling = siblingList[ index ];
00257             
00258             TiXmlElement* node = new TiXmlElement( sibling->name );
00259             xmlParent->LinkEndChild( node );
00260              
00261             // Set text data.
00262             if( sibling->value != "" && sibling->children.size() == 0 ){
00263 
00264                 // Escape "<" to avoid corruption of XML format.
00265                 String value = sibling->value;
00266                 value.find_and_replace( "<", "&lt;" );
00267                 
00268                 TiXmlText* text = new TiXmlText( value );
00269                 node->LinkEndChild( text );
00270             }
00271 
00272             // Set attributes
00273             AttributeMap &attr = sibling->attributes;
00274             for( AttributeMap::iterator i = attr.begin();
00275                  i != attr.end();
00276                  ++i
00277              ){
00278                  node->SetAttribute( i->first, i->second->value );
00279             }
00280 
00281             ConvertMapToXML( node, sibling );
00282          }
00283     }
00284 
00285 
00286 }
00287 
00288 // Load a passed XMLfile.
00289 void ParamXMLTree::LoadXMLFile( const String& fileName, bool stDefault )
00290 {
00291     TiXmlDocument doc;
00292     doc.LoadFile( fileName );
00293     CheckXMLParseError( doc, fileName );
00294 
00295     int inputIndex = (int)m_inputList.size();
00296     ConvertXMLToMap( m_root, &doc, inputIndex, stDefault );
00297     InputInfo info;
00298     info.fileName = fileName;
00299     info.type = InputInfo::IT_FILE;
00300     m_inputList.push_back( info);
00301 }
00302 
00303 // Load a passed raw XML string.
00304 void ParamXMLTree::LoadString( const String& xmlString, bool stDefault, const String& signature )
00305 {
00306     TiXmlDocument doc;
00307     doc.Parse( xmlString );
00308     CheckXMLParseError( doc, signature );
00309 
00310     int inputIndex = (int)m_inputList.size();
00311     InputInfo info;
00312     info.fileName = signature;
00313     info.type = InputInfo::IT_STRING;
00314     m_inputList.push_back( info);
00315     ConvertXMLToMap( m_root, &doc, inputIndex, stDefault );
00316 }
00317 
00318 // Load a passed value.
00319 void ParamXMLTree::LoadValue( const ParamXMLPath& path, const String& value )
00320 {
00321     int inputIndex = (int)m_inputList.size();
00322     InputInfo info;
00323     info.type = InputInfo::IT_CMD;
00324     m_inputList.push_back( info);
00325 
00326     Set( path, value, true );
00327     GetNode( path )->inputIndex = inputIndex;
00328 }
00329 
00330 // Convert the map to a Tiny XML document object.
00331 void ParamXMLTree::ToXMLDoc( TiXmlDocument& doc )
00332 {
00333     ConvertMapToXML( &doc, m_root );
00334 }
00335 
00336 // Convert the map to a string.
00337 String ParamXMLTree::ToXMLString()
00338 {
00339     TiXmlDocument dstDoc;
00340 
00341     TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "UTF-8", "" );  
00342     dstDoc.LinkEndChild( decl ); 
00343 
00344     ConvertMapToXML( &dstDoc, m_root );
00345 
00346     // Use an original TiXmlPrinter printer;
00347     ParamXMLPrinter printer;
00348     dstDoc.Accept( &printer );
00349     return String( printer.CStr() );
00350 }
00351 
00352 //
00353 void ParamXMLTree::Set( const ParamXMLPath& path, const String& value, bool forceOverWrite )
00354 {
00355     NodePtr node = m_root;
00356     for( ParamXMLPath::const_iterator i = path.begin();
00357          i != path.end();
00358          ++i
00359     ){
00360         ParamXMLPath::NodePtr pathNode = *i;
00361         if( pathNode->type == ParamXMLPath::NT_ARRAY ){
00362             // Array
00363             ChildMap::iterator next = node->children.find( pathNode->str );
00364             if( next == node->children.end() ){
00365                 node->children[ pathNode->str ] = NodeArray();
00366                 next = node->children.find( pathNode->str );
00367             }
00368 
00369             NodeArray& nodeList = next->second;
00370             size_t arrayIndex  = pathNode->arrayIndex;
00371             for( size_t i = nodeList.size(); i < arrayIndex + 1; i++ ){
00372                 NodePtr newNode = NodePtr( new Node() );
00373                 newNode->status = node->status;
00374                 newNode->name   = pathNode->str;
00375                 nodeList.push_back( newNode );
00376             }
00377             node = nodeList[ arrayIndex ];
00378 
00379         }
00380         else if( pathNode->type == ParamXMLPath::NT_ATTRIBUTE ){
00381             // attribute
00382             NodePtr newAttr( new Node() );
00383             newAttr->name  = pathNode->str;
00384             newAttr->value = value;
00385             newAttr->accessed = true;
00386 
00387             AttributeMap::iterator oldAttr = 
00388                 node->attributes.find( pathNode->str );
00389 
00390             if( oldAttr == node->attributes.end() ){
00391                 node->attributes[ pathNode->str ] = newAttr;
00392             }
00393             else{
00394                 if( !forceOverWrite &&
00395                     node->status.stReadOnly && 
00396                     oldAttr->second->value != value
00397                 ){
00398                     THROW_RUNTIME_ERROR( 
00399                         "The path '%s' is read only. The value is changed from '%s' to '%s'",
00400                         path.ToString().c_str(),
00401                         oldAttr->second->value.c_str(),
00402                         value.c_str()
00403                     );
00404                 }
00405 
00406                 oldAttr->second = newAttr;
00407             }
00408             return;
00409         }
00410         else if( pathNode->type == ParamXMLPath::NT_COUNT_FUNCTION ){
00411             // Count function
00412             // ???
00413             RUNTIME_WARNING( "Count function?" );
00414             return;
00415         }
00416         else if( pathNode->type == ParamXMLPath::NT_TEXT ){
00417             
00418             // Text
00419             node->accessed = true;
00420 
00421             // When 'text()' is referenced, its node must be already created,
00422             // thus a new node does not need to be created.
00423             // Text data is written to 'value' of its node.
00424             if( !forceOverWrite &&
00425                 node->status.stReadOnly && 
00426                 node->value != value
00427             ){
00428                 THROW_RUNTIME_ERROR( 
00429                     "The path '%s' is read only. The value is changed from '%s' to '%s'",
00430                     path.ToString().c_str(),
00431                     node->value.c_str(),
00432                     value.c_str()
00433                 );
00434             }
00435             node->value = value;
00436 
00437             return;
00438         }
00439         else{
00440             // Normal node
00441             ChildMap::iterator next = node->children.find( pathNode->str );
00442             if( next == node->children.end() ){
00443                 node->children[ pathNode->str ] = NodeArray();
00444                 next = node->children.find( pathNode->str );
00445             }
00446 
00447             NodeArray& nodeList = next->second;
00448             if( nodeList.size() < 1 ){
00449                 NodePtr newNode = NodePtr( new Node() );
00450                 newNode->status = node->status;
00451                 newNode->name   = pathNode->str;
00452                 nodeList.push_back( newNode );
00453             }
00454             node = nodeList[0];
00455         }
00456     }
00457 }
00458 
00459 //
00460 bool ParamXMLTree::Get( const ParamXMLPath& path, String* value, NodeStatus* status )
00461 {
00462     NodePtr node = m_root;
00463     for( ParamXMLPath::const_iterator i = path.begin();
00464          i != path.end();
00465          ++i
00466     ){
00467         ParamXMLPath::NodePtr pathNode = *i;
00468         if( pathNode->type == ParamXMLPath::NT_ARRAY ){
00469             // Array
00470             ChildMap::iterator next = node->children.find( pathNode->str );
00471             if( next != node->children.end() ){
00472                 if( (size_t)pathNode->arrayIndex >= next->second.size()  ){
00473                 if(status)
00474                     *status = node->status;
00475                     return false;
00476                 }
00477                 node = next->second[pathNode->arrayIndex];
00478             }
00479             else{
00480                 if(status)
00481                     *status = node->status;
00482                 return false;
00483             }
00484         }
00485         else if( pathNode->type == ParamXMLPath::NT_ATTRIBUTE ){
00486             // attribute
00487             AttributeMap::iterator attribute =
00488                 node->attributes.find( pathNode->str );
00489 
00490             if( attribute != node->attributes.end() ){
00491                 if(status)
00492                     *status = attribute->second->status;
00493                 *value = attribute->second->value;
00494                 attribute->second->accessed = true;
00495                 return true;
00496             }
00497             else{
00498                 if(status)
00499                     *status = node->status;
00500                 return false;
00501             }
00502         }
00503         else if( pathNode->type == ParamXMLPath::NT_COUNT_FUNCTION ){
00504             // Count function
00505             if(status)
00506                 *status = node->status;
00507             ChildMap::iterator next = node->children.find( pathNode->str );
00508             if( next != node->children.end() ){
00509                 *value = lexical_cast<String>( next->second.size() );
00510                 return true;
00511             }
00512             else{
00513                 return false;
00514             }
00515         }
00516         else if( pathNode->type == ParamXMLPath::NT_TEXT ){
00517             // Text
00518             if(status){
00519                 *status = node->status;
00520             }
00521             *value = node->value;
00522             return true;
00523         }
00524         else{
00525             // Normal node
00526             ChildMap::iterator next = node->children.find( pathNode->str );
00527             if( next != node->children.end() ){
00528                 if( next->second.size() == 0 ){
00529                     THROW_RUNTIME_ERROR( 
00530                         "The node map is borken.\n"
00531                         "'%s' has not child.\n"
00532                         "path: %s",
00533                         pathNode->str.c_str(),
00534                         path.ToString().c_str()
00535                     );
00536                 }
00537                 else if( next->second.size() != 1 ){
00538                     THROW_RUNTIME_ERROR( 
00539                         "The specified path '%s' is array.\n"
00540                         "path: %s",
00541                         pathNode->str.c_str(),
00542                         path.ToString().c_str()
00543                     );
00544                 }
00545 
00546                 node = next->second[0];
00547             }
00548             else{
00549                 if(status)
00550                     *status = node->status;
00551                 return false;
00552             }
00553         }
00554     }
00555     if(status)
00556         *status = node->status;
00557     return false;
00558 }
00559 
00560 
00561 ParamXMLTree::NodePtr 
00562 ParamXMLTree::GetNode( const ParamXMLPath& path, bool addNewNode )
00563 {
00564     NodePtr node = m_root;
00565     for( ParamXMLPath::const_iterator i = path.begin();
00566          i != path.end();
00567          ++i
00568     ){
00569         ParamXMLPath::NodePtr pathNode = *i;
00570         if( pathNode->type == ParamXMLPath::NT_ARRAY ){
00571             // Array
00572             ChildMap::iterator child = node->children.find( pathNode->str );
00573 
00574             if( child == node->children.end() ){
00575                 if( addNewNode ){
00576                     // Can not find a child node and add a new node
00577                     node->children[ pathNode->str ] = NodeArray();
00578                     child = node->children.find( pathNode->str );
00579                 }
00580                 else{
00581                     // Failed
00582                     return NodePtr();
00583                 }
00584             }
00585 
00586             NodeArray& childList = child->second;
00587             size_t arrayIndex  = pathNode->arrayIndex;
00588 
00589             if( childList.size() <= arrayIndex ){
00590                 if( addNewNode ){
00591                     //
00592                     for( size_t i = childList.size(); i < arrayIndex + 1; i++ ){
00593                         NodePtr newNode = NodePtr( new Node() );
00594                         newNode->status = node->status;
00595                         newNode->name   = pathNode->str;
00596                         childList.push_back( newNode );
00597                     }
00598                 }
00599                 else{
00600                     // Failed
00601                     return NodePtr();
00602                 }
00603             }
00604 
00605             node = childList[ arrayIndex ];
00606 
00607         }
00608         else if( pathNode->type == ParamXMLPath::NT_ATTRIBUTE ){
00609             // attribute
00610             AttributeMap::iterator attribute =
00611                 node->attributes.find( pathNode->str );
00612 
00613             if( attribute != node->attributes.end() ){
00614                 return attribute->second;
00615             }
00616             else{
00617                 if( addNewNode ){
00618                     if( node->status.stReadOnly ){
00619                         THROW_RUNTIME_ERROR( 
00620                             "The path '%s' is read only.",
00621                             path.ToString().c_str()
00622                         );
00623                     }
00624 
00625                     NodePtr newAttribute( new Node() );
00626                     newAttribute->name  = pathNode->str;
00627                     node->attributes[ pathNode->str ] = newAttribute;
00628                     return newAttribute;
00629                 }
00630                 else{
00631                     return NodePtr();
00632                 }
00633             }
00634         }
00635         else if( pathNode->type == ParamXMLPath::NT_COUNT_FUNCTION ){
00636             // Count function
00637             THROW_RUNTIME_ERROR( "Count function is not support." );
00638             return NodePtr();
00639         }
00640         else{
00641             // Normal node
00642             ChildMap::iterator child = node->children.find( pathNode->str );
00643             if( child == node->children.end() ){
00644                 if( addNewNode ){
00645                     node->children[ pathNode->str ] = NodeArray();
00646                     child = node->children.find( pathNode->str );
00647                 }
00648                 else{
00649                     return NodePtr();
00650                 }
00651             }
00652 
00653             NodeArray& nodeList = child->second;
00654             if( nodeList.size() < 1 ){
00655                 if( addNewNode ){
00656                     NodePtr newNode = NodePtr( new Node() );
00657                     newNode->status = node->status;
00658                     newNode->name   = pathNode->str;
00659                     nodeList.push_back( newNode );
00660                 }
00661                 else{
00662                     return NodePtr();
00663                 }
00664             }
00665             node = nodeList[0];
00666         }
00667     }
00668     return node;
00669 }
00670 
00671 ParamXMLTree::NodeArray* 
00672 ParamXMLTree::GetNodeArray( NodePtr parentNode, const String& childName, bool addNewNode )
00673 {
00674     ChildMap::iterator child = 
00675         parentNode->children.find( childName );
00676     if( child != parentNode->children.end() )
00677         return &child->second;
00678 
00679     if( addNewNode )
00680         return &parentNode->children[ childName ];
00681     else
00682         return NULL;
00683 }
00684 
00685 ParamXMLTree::NodeArray* 
00686 ParamXMLTree::GetNodeArray( const ParamXMLPath& orgPath, bool addNewNode )
00687 {
00688     ParamXMLPath path = orgPath;
00689     path.pop_back();
00690 
00691     NodePtr node = GetNode( path, addNewNode );
00692     if( node == NULL ){
00693         return NULL;
00694     }
00695 
00696     return GetNodeArray( node, orgPath.back()->str, addNewNode );
00697 }
00698 
00699 ParamXMLTree::NodePtr
00700 ParamXMLTree::GetAttribute( NodePtr parentNode, const String& attributeName, bool addNewNode )
00701 {
00702     AttributeMap::iterator attribute = 
00703         parentNode->attributes.find( attributeName );
00704     if( attribute != parentNode->attributes.end() )
00705         return attribute->second;
00706 
00707     if( addNewNode )
00708         return parentNode->attributes[ attributeName ];
00709     else
00710         return NodePtr();
00711 }
00712 
00713 
00714 
00715 const std::vector<ParamXMLTree::InputInfo>& ParamXMLTree::GetInputList()
00716 {
00717     return m_inputList;
00718 }
00719 
00720 bool ParamXMLTree::GetSourceXMLFile( const ParamXMLPath& path, String& fileName )
00721 {
00722     NodePtr node = GetNode( path );
00723     if( node == NULL ){
00724         return false;
00725     }
00726 
00727     if( node->inputIndex == -1 || node->inputIndex >= (int)m_inputList.size() ){
00728         return false;
00729     }
00730 
00731     InputInfo& info = m_inputList[node->inputIndex];
00732     if( info.type != InputInfo::IT_FILE )
00733         return false;
00734 
00735     fileName = info.fileName;
00736     return true;
00737 }

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