OpenTracker

An Open Architecture for Reconfigurable Tracking based on XML | Contact

Node.cxx

Go to the documentation of this file.
00001 /* ========================================================================
00002  * Copyright (c) 2006,
00003  * Institute for Computer Graphics and Vision
00004  * Graz University of Technology
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions are
00009  * met:
00010  *
00011  * Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the following disclaimer.
00013  *
00014  * Redistributions in binary form must reproduce the above copyright
00015  * notice, this list of conditions and the following disclaimer in the
00016  * documentation and/or other materials provided with the distribution.
00017  *
00018  * Neither the name of the Graz University of Technology nor the names of
00019  * its contributors may be used to endorse or promote products derived from
00020  * this software without specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00023  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00024  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00025  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00026  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00027  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00028  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00029  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00030  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00031  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00032  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  * ========================================================================
00034  * PROJECT: OpenTracker
00035  * ======================================================================== */
00043 /* ======================================================================= */
00044 
00045 #include <cstdio>
00046 #include <iostream>
00047 
00048 #include <memory>
00049 #include <algorithm>
00050 
00051 #include "../OpenTracker.h"
00052 
00053 // selects between usage of XERCES and TinyXML
00054 #include "../tool/XMLSelection.h"
00055 
00056 #ifdef USE_XERCES
00057 #include <xercesc/dom/DOM.hpp>
00058 #include <xercesc/util/XMLString.hpp>
00059 #include <xercesc/util/XMLUniDefs.hpp>
00060 #endif //USE_XERCES
00061 
00062 #include "Node.h"
00063 #include "StringTable.h"
00064 #include "Context.h"
00065 
00066 //using namespace std;
00067 
00068 #ifdef USE_XERCES
00069 #define ELEMENT(a) ((XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *)a)
00070 XERCES_CPP_NAMESPACE_USE
00071 #endif //USE_XERCES
00072 
00073 #ifdef USE_TINYXML
00074 #define ELEMENT(a) ((TiXmlElement*)a)
00075 #endif //USE_TINYXML
00076 
00077 namespace ot {
00078 
00079 
00080     // emtpy string to be returned, if key is not in the map
00081     // the object itself is part of StringTable.cxx
00082     extern const std::string empty("");
00083 
00084 #ifdef USE_XERCES
00085     const XMLCh ud_node[] = { chLatin_n, chLatin_o, chLatin_d, chLatin_e, chNull };
00086 #endif //USE_XERCES
00087 
00088 
00089     // constructor
00090     Node::Node() : name("")
00091     {
00092         parent = NULL;
00093     }
00094 
00095     // destructor
00096 
00097     Node::~Node()
00098     {
00099         references.clear();
00100         if( parent != NULL )
00101         {
00102 #ifdef USE_XERCES
00103             try {
00104                 ELEMENT(parent)->release();
00105             }
00106             catch(DOMException &)
00107             {
00108             }
00109 #endif //USE_XERCES
00110 
00111 #ifdef USE_TINYXML
00112             delete ELEMENT(parent);
00113 #endif //USE_TINYXML
00114         }
00115     }
00116 
00117     // sets the DOM_Element this node belongs to ( not the parent in OT )
00118 
00119     void Node::setParent( void * parElement )
00120     {
00121 #ifdef USE_XERCES
00122         parent = parElement;
00123         ELEMENT(parent)->setUserData( ud_node, this, NULL );
00124         char * temp = XMLString::transcode(ELEMENT(parent)->getLocalName());
00125         type = temp;
00126         XMLString::release( &temp );
00127 #endif //USE_XERCES
00128 
00129 #ifdef USE_TINYXML
00130         parent = parElement;
00131         ELEMENT(parent)->SetUserData(this);
00132         const char* temp = ELEMENT(parent)->Value();
00133         type = temp;
00134 #endif //USE_TINYXML
00135     }
00136 
00137     // adds a reference to the node
00138 
00139     void Node::addReference( Node * reference )
00140     {
00141         references.push_back( reference );
00142     }
00143 
00144     // removes a reference from the node
00145 
00146     void Node::removeReference( Node * reference )
00147     {
00148         NodeVector::iterator result = std::find( references.begin(), references.end(),
00149                                                  reference );
00150         if( result != references.end())
00151         {
00152             references.erase( result );
00153         }
00154     }
00155 
00156     // returns a pointer to the parent node
00157 
00158     Node * Node::getParent()
00159     {
00160 #ifdef USE_XERCES
00161         DOMNode * parentElement = ELEMENT(parent)->getParentNode();
00162         if( parentElement != 0 )
00163         {
00164             return (Node *)parentElement->getUserData(ud_node);
00165         }
00166         return NULL;
00167 #endif //USE_XERCES
00168 
00169 #ifdef USE_TINYXML
00170         TiXmlNode * parentElement = ELEMENT(parent)->Parent();
00171         if( parentElement != 0 )
00172         {
00173             return (Node *)parentElement->GetUserData();
00174         }
00175         return NULL;
00176 #endif //USE_TINYXML
00177     }
00178 
00179     // returns the Context this node lives in
00180 
00181     Context * Node::getContext() const
00182     {
00183 #ifdef USE_XERCES
00184         DOMDocument * doc = ELEMENT(parent)->getOwnerDocument();
00185         if( doc != 0)
00186         {
00187             return (Context *)doc->getUserData(ud_node);
00188         }
00189         return NULL;
00190 #endif //USE_XERCES
00191 
00192 #ifdef USE_TINYXML
00193         TiXmlDocument * doc = ELEMENT(parent)->GetDocument();
00194         if( doc != 0)
00195         {
00196             return (Context *)doc->GetUserData();
00197         }
00198         return NULL;
00199 #endif //USE_TINYXML
00200     }
00201 
00202     // returns the number of children
00203 
00204     unsigned int Node::countChildren()
00205     {
00206 #ifdef USE_XERCES
00207         DOMNode * node = ELEMENT(parent)->getFirstChild();
00208         unsigned int count = 0;
00209         while( node != NULL )
00210         {
00211             Node * myNode = (Node *)node->getUserData(ud_node);
00212             if( myNode != NULL )
00213             {
00214                 if( myNode->isNodePort() == 0 )
00215                     count ++;
00216             }
00217             node = node->getNextSibling();
00218         }
00219         return count;
00220 #endif //USE_XERCES
00221 
00222 #ifdef USE_TINYXML
00223         TiXmlNode * node = ELEMENT(parent)->FirstChild();
00224         unsigned int count = 0;
00225         while( node != NULL )
00226         {
00227             Node * myNode = (Node *)node->GetUserData();
00228             if( myNode != NULL )
00229             {
00230                 if( myNode->isNodePort() == 0 )
00231                     count ++;
00232             }
00233             node = node->NextSibling();
00234         }
00235         return count;
00236 #endif //USE_TINYXML
00237     }
00238 
00239     // adds a new child
00240 
00241     Node::error Node::addChild(Node & child)
00242     {
00243 #ifdef USE_XERCES
00244         try {
00245             ELEMENT(parent)->appendChild( ELEMENT(child.parent));
00246         }
00247         catch( DOMException e )
00248         {
00249             return GRAPH_CONSTRAINT;
00250         }
00251         return OK;
00252 #endif //USE_XERCES
00253 
00254 #ifdef USE_TINYXML
00255         ELEMENT(parent)->InsertEndChild( *ELEMENT(child.parent));
00256         return OK;
00257 #endif //USE_TINYXML
00258     }
00259 
00260     // removes a child
00261 
00262     Node::error Node::removeChild(Node & child)
00263     {
00264 #ifdef USE_XERCES
00265         try {
00266             ELEMENT(parent)->removeChild( ELEMENT(child.parent));
00267         }
00268         catch( DOMException e )
00269         {
00270             return NOT_FOUND;
00271         }
00272         return OK;
00273 #endif //USE_XERCES
00274 
00275 #ifdef USE_TINYXML
00276         ELEMENT(parent)->RemoveChild( ELEMENT(child.parent));
00277         return OK;
00278 #endif //USE_TINYXML
00279     }
00280 
00281     // iterates through the children by returning the child by index
00282 
00283     Node * Node::getChild( unsigned int index )
00284     {
00285 #ifdef USE_XERCES
00286         Node * myNode = NULL;
00287         DOMNode * node = ELEMENT(parent)->getFirstChild();
00288         while( node != NULL )
00289         {
00290             myNode = (Node *)node->getUserData(ud_node);
00291             if( myNode != NULL )
00292                 if( myNode->isNodePort() == 0 )
00293                     if( index == 0 )
00294                         return myNode;
00295                     else
00296                         index--;
00297             node = node->getNextSibling();
00298         }
00299         return NULL;
00300 #endif //USE_XERCES
00301 
00302 #ifdef USE_TINYXML
00303         Node * myNode = NULL;
00304         TiXmlNode * node = ELEMENT(parent)->FirstChild();
00305         while( node != NULL )
00306         {
00307             myNode = (Node *)node->GetUserData();
00308             if( myNode != NULL )
00309                 if( myNode->isNodePort() == 0 )
00310                     if( index == 0 )
00311                         return myNode;
00312                     else
00313                         index--;
00314             node = node->NextSibling();
00315         }
00316         return NULL;
00317 #endif //USE_TINYXML
00318     }
00319 
00320     // returns number of NodePorts present on this Node
00321 
00322     unsigned int Node::countPorts()
00323     {
00324 #ifdef USE_XERCES
00325         Node * myNode = NULL;
00326         unsigned int count = 0;
00327         DOMNode * node = ELEMENT(parent)->getFirstChild();
00328         while( node != NULL )
00329         {
00330             myNode = (Node *)node->getUserData(ud_node);
00331             if( myNode != NULL )
00332                 if( myNode->isNodePort() == 1 )
00333                     count++;
00334             node = node->getNextSibling();
00335         }
00336         return count;
00337 #endif //USE_XERCES
00338 
00339 #ifdef USE_TINYXML
00340         Node * myNode = NULL;
00341         unsigned int count = 0;
00342         TiXmlNode * node = ELEMENT(parent)->FirstChild();
00343         while( node != NULL )
00344         {
00345             myNode = (Node *)node->GetUserData();
00346             if( myNode != NULL )
00347                 if( myNode->isNodePort() == 1 )
00348                     count++;
00349             node = node->NextSibling();
00350         }
00351         return count;
00352 #endif //USE_TINYXML
00353     }
00354 
00355     // returns a NodePort child object indexed by Name and index
00356 
00357     NodePort * Node::getPort( const std::string & name, unsigned int index )
00358     {
00359 #ifdef USE_XERCES
00360         XMLCh * temp = XMLString::transcode( name.c_str());
00361         XMLCh * xmlspace = XMLString::transcode(getContext()->getRootNamespace().c_str());
00362         DOMNodeList * list = ELEMENT(parent)->getElementsByTagNameNS( xmlspace, temp );
00363         XMLString::release( &temp );
00364         XMLString::release( &xmlspace );
00365         if( list->getLength() > index )
00366         {
00367             DOMElement * portElement = (DOMElement *) list->item(index);
00368             Node * port = (Node *)portElement->getUserData(ud_node);
00369             if( port != NULL )
00370                 if( port->isNodePort() == 1 )
00371                     return (NodePort *)port;
00372         }
00373         return NULL;
00374 #endif //USE_XERCES
00375 
00376 #ifdef USE_TINYXML
00377         const char* temp = name.c_str();
00378         const char* xmlspace = getContext()->getRootNamespace().c_str();
00379         TiXmlNode * currentNode = NULL;
00380 
00381         while(currentNode = ELEMENT(parent)->IterateChildren(temp, currentNode))
00382         {
00383             Node * port = (Node *)currentNode->GetUserData();
00384             if( port != NULL )
00385                 if( port->isNodePort() == 1 )
00386                     // since there might be more than one Child with the same name
00387                     // we use the index to select the one we need.
00388                     if( index == 0 )
00389                         return (NodePort *) port;
00390                     else
00391                         index--;
00392             
00393         }
00394 
00395         return NULL;
00396 #endif //USE_TINYXML
00397     }
00398 
00399     // returns a NodePort child object by index
00400 
00401     NodePort * Node::getPort( unsigned int index )
00402     {
00403 #ifdef USE_XERCES
00404         Node * myNode = NULL;
00405         DOMNode * node = ELEMENT(parent)->getFirstChild();
00406         while( NULL != node )
00407         {
00408             myNode = (Node *)node->getUserData(ud_node);
00409             if( myNode != NULL )
00410                 if( myNode->isNodePort() == 1 )
00411                     if( index == 0 )
00412                         return (NodePort *) myNode;
00413                     else
00414                         index--;
00415             node = node->getNextSibling();
00416         }
00417         return NULL;
00418 #endif //USE_XERCES
00419 
00420 #ifdef USE_TINYXML
00421         Node * myNode = NULL;
00422         TiXmlNode * node = ELEMENT(parent)->FirstChild();
00423         while( NULL != node )
00424         {
00425             myNode = (Node *)node->GetUserData();
00426             if( myNode != NULL )
00427                 if( myNode->isNodePort() == 1 )
00428                     if( index == 0 )
00429                         return (NodePort *) myNode;
00430                     else
00431                         index--;
00432             node = node->NextSibling();
00433         }
00434         return NULL;
00435 #endif //USE_TINYXML
00436     }
00437 
00438     // creates and adds a new child NodePort object of the given name.
00439 
00440     Node::error Node::addPort( const std::string & name )
00441     {
00442 #ifdef USE_XERCES
00443         XMLCh * temp = XMLString::transcode( name.c_str());
00444         XMLCh * xmlspace = XMLString::transcode(getContext()->getRootNamespace().c_str());
00445         DOMNodeList * list = ELEMENT(parent)->getElementsByTagNameNS( xmlspace, temp );
00446         XMLString::release( &temp );
00447         XMLString::release( &xmlspace );
00448         if( list->getLength() > 0 )
00449         {
00450             return GRAPH_CONSTRAINT;
00451         }
00452         DOMDocument * doc = ELEMENT(parent)->getOwnerDocument();
00453         Context * context = (Context *)doc->getUserData( ud_node );
00454         StringTable table;
00455         Node * node = context->createNode( name, table);
00456         if( node == NULL )
00457             return GRAPH_CONSTRAINT;
00458         return addChild( *node );
00459 #endif //USE_XERCES
00460 
00461 #ifdef USE_TINYXML
00462         const char* temp = name.c_str();
00463         const char* xmlspace = getContext()->getRootNamespace().c_str();
00464         TiXmlNode * currentNode = NULL;
00465 
00466         if(ELEMENT(parent)->FirstChild(temp))
00467             return GRAPH_CONSTRAINT;
00468 
00469         TiXmlDocument * doc = ELEMENT(parent)->GetDocument();
00470         Context * context = (Context *)doc->GetUserData();
00471         StringTable table;
00472         Node * node = context->createNode( name, table);
00473         if( node == NULL )
00474             return GRAPH_CONSTRAINT;
00475         return addChild( *node );
00476 #endif //USE_TINYXML
00477     }
00478 
00479     // removes a child NodePort object indexed by name
00480 
00481     Node::error Node::removePort( const std::string & name )
00482     {
00483 #ifdef USE_XERCES
00484         NodePort * port = getPort( name );
00485         if( port == NULL )
00486             return NOT_FOUND;
00487         return removePort( *port );
00488 #endif //USE_XERCES
00489 
00490 #ifdef USE_TINYXML
00491         NodePort * port = getPort( name );
00492         if( port == NULL )
00493             return NOT_FOUND;
00494         return removePort( *port );
00495 #endif //USE_TINYXML
00496     }
00497 
00498     // removes a child NodePort object by index
00499 
00500     Node::error Node::removePort( unsigned int index )
00501     {
00502 #ifdef USE_XERCES
00503         NodePort * port = getPort( index );
00504         if( port == NULL )
00505             return NOT_FOUND;
00506         return removePort( *port );
00507 #endif //USE_XERCES
00508 
00509 #ifdef USE_TINYXML
00510         NodePort * port = getPort( index );
00511         if( port == NULL )
00512             return NOT_FOUND;
00513         return removePort( *port );
00514 #endif //USE_TINYXML
00515     }
00516 
00517     Node::error Node::removePort( NodePort & port)
00518     {
00519         return removeChild((Node &) port );
00520     }
00521 
00522     // updates any observers ( the parent and the references )
00523 
00524     void Node::updateObservers( Event &data )
00525     {
00526 #ifdef USE_XERCES
00527         if( isEventGenerator() == 1 || isNodePort() == 1 )
00528         {
00529             DOMNode * parentElement = ELEMENT(parent)->getParentNode();
00530             if( NULL != parentElement  )
00531             {
00532                 ((Node *)parentElement->getUserData( ud_node ))->onEventGenerated( data, *this );
00533             }
00534             for( NodeVector::iterator it = references.begin(); it != references.end(); it++ )
00535             {
00536                 (*it)->onEventGenerated( data, *this );
00537             }
00538         }
00539 #endif //USE_XERCES
00540 
00541 #ifdef USE_TINYXML
00542         if( isEventGenerator() == 1 || isNodePort() == 1 )
00543         {
00544             TiXmlNode * parentElement = ELEMENT(parent)->Parent();
00545             if( NULL != parentElement  )
00546             {
00547                 ((Node *)parentElement->GetUserData())->onEventGenerated( data, *this );
00548             }
00549             for( NodeVector::iterator it = references.begin(); it != references.end(); it++ )
00550             {
00551                 (*it)->onEventGenerated( data, *this );
00552             }
00553         }
00554 #endif //USE_TINYXML
00555     }
00556 
00557     // returns a value to a given key
00558 
00559     const std::string Node::get( const std::string & key ) const
00560     {
00561 #ifdef USE_XERCES
00562         XMLCh * temp = XMLString::transcode( key.c_str() );
00563         XMLCh * xmlspace = XMLString::transcode(getContext()->getRootNamespace().c_str());
00564         const XMLCh * res = ELEMENT(parent)->getAttributeNS( xmlspace, temp );
00565         XMLString::release( &temp );
00566         XMLString::release( &xmlspace );
00567         char * cres = XMLString::transcode( res );
00568         std::string result( cres );
00569         XMLString::release( &cres );
00570         return result;
00571 #endif //USE_XERCES
00572 
00573 #ifdef USE_TINYXML
00574         const char* temp  = key.c_str();
00575         const char* xmlspace = getContext()->getRootNamespace().c_str();
00576         const char* res = ELEMENT(parent)->Attribute(temp);
00577         return  std::string( res );
00578 #endif //USE_TINYXML
00579     }
00580 
00581     // stores a key, value pair
00582 
00583     void Node::put( const std::string & key, const std::string & value )
00584     {
00585 #ifdef USE_XERCES
00586         XMLCh * tempKey = XMLString::transcode( key.c_str() );
00587         XMLCh * tempValue = XMLString::transcode( value.c_str());
00588         XMLCh * xmlspace = XMLString::transcode(getContext()->getRootNamespace().c_str());
00589         ELEMENT(parent)->setAttributeNS( xmlspace, tempKey, tempValue );
00590         XMLString::release( & tempKey );
00591         XMLString::release( & tempValue );
00592         XMLString::release( & xmlspace );
00593 #endif //USE_XERCES
00594 
00595 #ifdef USE_TINYXML
00596         const char* tempKey = key.c_str();
00597         const char* tempValue = value.c_str();
00598         const char* xmlspace = getContext()->getRootNamespace().c_str();
00599         ELEMENT(parent)->SetAttribute( tempKey, tempValue);
00600 #endif //USE_TINYXML
00601     }
00602 
00603     // removes a key, value pair
00604 
00605     void Node::remove( const std::string & key )
00606     {
00607 #ifdef USE_XERCES
00608         XMLCh * tempKey = XMLString::transcode( key.c_str() );
00609         XMLCh * xmlspace = XMLString::transcode(getContext()->getRootNamespace().c_str());
00610         ELEMENT(parent)->removeAttributeNS( xmlspace, tempKey );
00611         XMLString::release( & tempKey );
00612         XMLString::release( & xmlspace );
00613 #endif //USE_XERCES
00614 
00615 #ifdef USE_TINYXML
00616         const char* tempKey = key.c_str();
00617         const char* xmlspace = getContext()->getRootNamespace().c_str();
00618         ELEMENT(parent)->RemoveAttribute( tempKey );
00619 #endif //USE_TINYXML
00620     }
00621 
00622     // some put and get methods
00623 
00624     void Node::put(const std::string & key, const int value)
00625     {
00626         char buffer[20];
00627 
00628         sprintf( buffer, "%i", value );
00629         put( key, buffer );
00630     }
00631 
00632     void Node::put(const std::string & key, const float value)
00633     {
00634         char buffer[20];
00635 
00636         sprintf( buffer, "%f", value );
00637         put( key, buffer );
00638     }
00639 
00640     void Node::put(const std::string & key, const double value)
00641     {
00642         char buffer[30];
00643 
00644         sprintf( buffer, "%lf", value );
00645         put( key, buffer );
00646     }
00647 
00648     void Node::put(const std::string & key, const int * value, int len)
00649     {
00650         char buffer[20];
00651         std::string strvalue;
00652 
00653         sprintf(buffer, "%i", value[0] );
00654         strvalue.append(buffer);
00655         for( int i = 1; i < len; i++ )
00656         {
00657             sprintf(buffer, " %i", value[i] );
00658             strvalue.append(buffer);
00659         }
00660         put( key, strvalue );
00661     }
00662 
00663     void Node::put(const std::string & key, const float * value, int len)
00664     {
00665         char buffer[20];
00666         std::string strvalue;
00667 
00668         sprintf(buffer, "%f", value[0] );
00669         strvalue.append(buffer);
00670         for( int i = 1; i < len; i++ )
00671         {
00672             sprintf(buffer, " %f", value[i] );
00673             strvalue.append(buffer);
00674         }
00675         put( key, strvalue );
00676     }
00677 
00678     void Node::put(const std::string & key, const double * value, int len)
00679     {
00680         char buffer[20];
00681         std::string strvalue;
00682 
00683         sprintf(buffer, "%lf", value[0] );
00684         strvalue.append(buffer);
00685         for( int i = 1; i < len; i++ )
00686         {
00687             sprintf(buffer, " %lf", value[i] );
00688             strvalue.append(buffer);
00689         }
00690         put( key, strvalue );
00691     }
00692 
00693     int Node::get(const std::string & key, int * value, int len ) const
00694     {
00695         std::string data = get( key );
00696         const char * start = data.c_str();
00697         char * end = (char *)start;
00698         int count = 0;
00699         value[count++] = strtol( start, &end, 0 );
00700         while( end != start && count < len){
00701             start = end;
00702             value[count++] = strtol( start, &end, 0 );
00703         }
00704         return count;
00705     }
00706 
00707     int Node::get(const std::string & key, float * value, int len ) const
00708     {
00709         std::string data = get( key );
00710         const char * start = data.c_str();
00711         char * end = (char *)start;
00712         int count = 0;
00713         value[count++] = (float)strtod( start, &end );
00714         while( end != start && count < len){
00715             start = end;
00716             value[count++] = (float)strtod( start, &end );
00717         }
00718         return count;
00719     }
00720 
00721     int Node::get(const std::string & key, double * value, int len ) const
00722     {
00723         std::string data = get( key );
00724         const char * start = data.c_str();
00725         char * end = (char *)start;
00726         int count = 0;
00727         value[count++] = strtod( start, &end );
00728         while( end != start && count < len){
00729             start = end;
00730             value[count++] = strtod( start, &end );
00731         }
00732         return count;
00733     }
00734 
00735 } // namespace ot
00736 
00737 /* 
00738  * ------------------------------------------------------------
00739  *   End of Node.cxx
00740  * ------------------------------------------------------------
00741  *   Automatic Emacs configuration follows.
00742  *   Local Variables:
00743  *   mode:c++
00744  *   c-basic-offset: 4
00745  *   eval: (c-set-offset 'substatement-open 0)
00746  *   eval: (c-set-offset 'case-label '+)
00747  *   eval: (c-set-offset 'statement 'c-lineup-runin-statements)
00748  *   eval: (setq indent-tabs-mode nil)
00749  *   End:
00750  * ------------------------------------------------------------ 
00751  */

copyright (c) 2006 Graz University of Technology