Exemple #1
0
CDataNode* 
CDataNode::Structure( const CString& sequence ,
                      char seperator          )
{GUCEF_TRACE;

    // walk the tree
    CString buildseg;
    TDataNodeVector walkResults = WalkTree( sequence  ,
                                            seperator ,
                                            buildseg  );
                 
    // do we need to add nodes ?
    if ( 0 < buildseg.Length() )
    {
        CDataNode* parentNode = this;
        if ( !walkResults.empty() )
            parentNode = *walkResults.begin(); 
        
        CDataNode child;
        CString name;
        while ( buildseg.Length() )
        {
            name = buildseg.SubstrToChar( seperator, true );
            child.SetName( name );                        
            buildseg = buildseg.CutChars( name.Length()+1, true );                        
            parentNode = parentNode->AddChild( child );
        }
        return parentNode;
    }
    
    if ( walkResults.empty() )
        return nullptr;
    return *walkResults.begin();        
}                      
Exemple #2
0
CDataNode* 
CDataNode::Search( const CString& query     ,
                   char seperator           ,
                   bool fromcurrent         ,
                   bool treatChildAsCurrent ) const
{GUCEF_TRACE;

    if ( fromcurrent )
    {
        CString thisname( query.SubstrToChar( seperator, true ) );
        if ( thisname == _name )
        {
            CString remnant( query.CutChars( thisname.Length()+1, true ) );
            if ( remnant.Length() > 0 )
            {            
                CString leftover;
                TDataNodeVector results = WalkTree( remnant   ,
                                                    seperator ,
                                                    leftover  );
                if ( 0 == leftover.Length() && !results.empty() )
                {       
                    return *results.begin();
                }                                 
            }
            else
            {   
                // this node is the leaf node we are searching for
                return const_cast< CDataNode* >( this );
            }
        }
        else
        if ( treatChildAsCurrent )
        {
            TDataNodeList::const_iterator i = m_children.begin();
            while ( i != m_children.end()  )
            {
                CDataNode* result = (*i)->Search( query       ,
                                                  seperator   ,
                                                  fromcurrent ,
                                                  false       );                
                if ( nullptr != result )
                    return result;
                ++i;
            }
        }
        return nullptr;                                            
    }
    else
    {
        CString leftover;
        TDataNodeVector results = WalkTree( query     ,
                                            seperator ,
                                            leftover  );
        if ( 0 == leftover.Length() && !results.empty() )
        {       
            return *results.begin();
        }
        return nullptr;
    }                
}
CString
CIniParser::StripQuotation( const CString& testString )
{GUCEF_TRACE;

    CString resultStr = testString.Trim( true ).Trim( false );
    if ( resultStr.Length() > 1 )
    {
        if ( ( resultStr[ 0 ] == '\"' ) && ( resultStr[ resultStr.Length()-1 ] == '\"' ) )
        {
            return resultStr.SubstrFromRange( 1, resultStr.Length()-1 );
        }
    }
    return resultStr;
}
Exemple #4
0
CDataNode*
CDataNode::Structure( const CString& nodeName       ,
                      const CString& attribName     ,
                      const CString& attribSequence ,
                      const char seperator          )
{GUCEF_TRACE;

    // Prepare some variables for the first loop iteration
    CDataNode* node = this;
    CString attSeqRemnant = attribSequence;
    CString attValue = attSeqRemnant.SubstrToChar( seperator );
    bool childExists = true;
    CDataNode* childNode = NULL;
    
    do
    {
        // First we check if we can skip the search for a child node
        // This is a minor optimization        
        if ( childExists )
        {
            // See if there already is a node of the given type
            childNode = node->FindChild( nodeName   ,
                                         attribName ,
                                         attValue   );
            if ( childNode == NULL )
            {
                childExists = false;
            }
        }
        
        // Check if we have to create a new node
        if ( childNode == NULL )
        {
            // No such node exists, we will create it
            CDataNode newChild( nodeName );
            newChild.AddAttribute( attribName, attValue );
            childNode = node->AddChild( newChild );
        }
        
        node = childNode;
        
        // Get the next segment
        attSeqRemnant = attSeqRemnant.CutChars( attValue.Length()+1, true );
        attValue = attSeqRemnant.SubstrToChar( seperator );
        
    } while ( attSeqRemnant.Length() > 0 );
    
    return childNode;
}
const CValue* CXMLBoundValueChildNode::Evaluate(_IN SCFXML::CXMLNode& rCurrent) const
{
	if (BoundValueChildNode_pValue) { delete BoundValueChildNode_pValue; BoundValueChildNode_pValue = nullptr; }

	if (rCurrent.Type() == XmlElement)
	{
		CXMLNode* pChild = ((CXMLElement&)rCurrent).ChildFirst();
		while (pChild)
		{
			if (pChild->Name() == m_Name)
			{
				UINT uiCharsParsed = 0;

				CString valueString = pChild->Value() ? pChild->Value()->ToString() : "";

				BoundValueChildNode_pValue = &CValue::Parse(valueString, &uiCharsParsed);

				for (UINT i = uiCharsParsed; i < valueString.Length(); i++)
				{
					if (!CharIsWhiteSpace(valueString[i])) {

						if (BoundValueChildNode_pValue) { delete BoundValueChildNode_pValue; BoundValueChildNode_pValue = nullptr; }

						BoundValueChildNode_pValue = new STRING_RETURN(valueString); 
					}
				}

				return BoundValueChildNode_pValue;
			}
		}
	}

	return nullptr;
}
Exemple #6
0
void CLinkCache::Purge(const CDDEConv* pConv)
{
	typedef CLinksMap::iterator LinksIter;

	CStrArray astrLinks;

	// Format the cache entry prefix for the conversation.
	CString strPrefix = CString::Fmt(TXT("%s|%s!"), pConv->Service().c_str(), pConv->Topic().c_str());
	size_t  nLength   = strPrefix.Length();

	// Find all links for the conversation...
	for (LinksIter it = m_oLinks.begin(); it != m_oLinks.end(); ++it)
	{
		const CString& strLink = it->first;

		if (tstrnicmp(strLink, strPrefix, nLength) == 0)
		{
			// Delete value, but remember key.
			astrLinks.Add(strLink);
			delete it->second;
		}
	}

	// Purge all matching links...
	for (size_t i = 0; i < astrLinks.Size(); ++i)
		m_oLinks.erase(astrLinks[i]);
}
void
CNotificationIDRegistry::Unregister( const CString& keyvalue                      ,
                                     const bool okIfUnknownKeyGiven /* = false */ )
{GUCEF_TRACE;

    m_dataLock.Lock();

    if ( keyvalue.Length() > 0 )
    {
        TRegistryList::iterator i = m_list.find( keyvalue );
        if ( i != m_list.end() )
        {
            m_list.erase( i );
        }
        else
        {
            m_dataLock.Unlock();
            GUCEF_EMSGTHROW( EUnknownKey, "CNotificationIDRegistry::Unregister(): unknown notification key string identifier" );
        }
    }
    else
    {
        m_dataLock.Unlock();
        GUCEF_EMSGTHROW( EUnknownKey, "CNotificationIDRegistry::Unregister(): invalid notification key string identifier" );
    }

    m_dataLock.Unlock();
}
Exemple #8
0
size_t CIniFile::ReadSection(const tchar* pszSection, CStrArray& astrKeys, CStrArray& astrValues)
{
	ASSERT(pszSection);

	CStrArray astrEntries;

	// Read all the entries...
	if (ReadSection(pszSection, astrEntries))
	{
		// Split all entries.
		for (size_t i = 0; i < astrEntries.Size(); ++i)
		{
			// Split into key and value.
			CString strEntry = astrEntries[i];
			size_t  nLength  = strEntry.Length();
			size_t  nSepPos  = strEntry.Find(TXT('='));

			// Key set AND value set?
			if ( (nSepPos > 0) && ((nLength-nSepPos-1) > 0) )
			{
				astrKeys.Add(strEntry.Left(nSepPos));
				astrValues.Add(strEntry.Right(nLength-nSepPos-1));
			}
		}
	}

	ASSERT(astrKeys.Size() == astrValues.Size());

	return astrKeys.Size();
}
Exemple #9
0
 bool CString::operator==(const CString& str) const {
   if (length_ != str.Length()) {
     return false;
   }
   else {
     return Compare(str) == 0;
   }
 }
bool
CIniParser::LoadFrom( const CString& iniText )
{GUCEF_TRACE;

    CDynamicBuffer stringBuffer;
    stringBuffer.LinkTo( iniText.C_String(), iniText.Length() );
    CDynamicBufferAccess stringBufferAccess( &stringBuffer, false );
    return LoadFrom( stringBufferAccess );
}
Exemple #11
0
  CString::CString(const CString& str)
  : length_(str.Length())
  , reserved_(0) {
    if ((string_ = static_cast<char*>(::malloc(length_ + 1))) == 0) {
      base_throw(InternalError, "malloc failed");
    }

    ::memcpy(static_cast<void*>(string_), str.Str(), length_);
    string_[length_] = '\0';
  }
Exemple #12
0
CString
CDataNode::GetAttributeValueOrChildValueByName( const CString& name ) const
{
    CString value = GetAttributeValue( name );
    if ( 0 == value.Length() )
    {
        value = GetChildValueByName( name );
    }
    return value;
}
Exemple #13
0
bool CThread::MaskMatch(CString sStr, CString sMask)
{
	sStr.ToLower();

	LPTSTR cp = 0;
	LPTSTR mp = 0;

	LPTSTR s = new TCHAR[sStr.Length() + 1];
	LPTSTR mask = new TCHAR[sMask.Length() + 1];

	lstrcpy(s, sStr.C());
	lstrcpy(mask, sMask.C());

	for (; *s&& *mask != TEXT('*'); mask++, s++)
		if (*mask != *s && *mask != TEXT('?')) return false;

	for (;;)
	{
		if (!*s)
		{
			while (*mask == TEXT('*')) mask++;
			return !*mask;
		}

		if (*mask == TEXT('*'))
		{
			if (!*++mask) return true;
			
			mp = mask;
			cp=s+1;
			continue;
		}

		if (*mask == *s || *mask == TEXT('?'))
		{
			mask++, s++;
			continue;
		}

		mask = mp; s = cp++;
	}
}
void
CMsWin32Editbox::AppendLine( const CString& line )
{GUCEF_TRACE;

    CString currentText = GetText();
    if ( currentText.Length() > 0 )
    {
        char lastChar = currentText[ currentText.Length()-1 ];
        if ( lastChar == '\n' || lastChar == '\r' )
        {
            currentText += line;
        }
        else
        {
            currentText += "\r\n" + line;
        }
        SetText( currentText );
    }
    else
    {
        SetText( line );
    }
}
Exemple #15
0
void
CGUIManager::OnNotify( GUCEF::CORE::CNotifier* notifier                  ,
                       const GUCEF::CORE::CEvent& eventid                ,
                       GUCEF::CORE::CICloneable* eventdata /* = NULL  */ )
{GUCE_TRACE;
    
    if ( GUCEF::GUI::CGUIManager::DriverRegisteredEvent == eventid )
    {
        // Check if the registered driver has a GUCE interface so we can use it
        // at this level. First get the information about the driver
        CString& driverName = static_cast< GUCEF::CORE::TCloneableString* >( eventdata )->GetData();
        GUCEF::GUI::CGUIDriver* basicGucefDriver = GUCEF::GUI::CGUIManager::Instance()->GetGuiDriver( driverName );        
        
        // Now get the property telling us whether its GUCE capable
        CString hasGuceInterfaceStr = basicGucefDriver->GetDriverProperty( CIGUIDriver::HasGuceInterfaceDriverProperty );
        if ( ( hasGuceInterfaceStr.Length() > 0 )                &&
             ( GUCEF::CORE::StringToBool( hasGuceInterfaceStr ) ) )
        {        
            // The newly registered driver is GUCE compatible/capable
            // We register it here for use
            GUCE::GUI::CIGUIDriver* guceDriver = static_cast< GUCE::GUI::CIGUIDriver* >( basicGucefDriver );
            RegisterGUIDriver( driverName, *guceDriver );
        }
    }
    else
    if ( GUCEF::GUI::CGUIManager::DriverUnregisteredEvent == eventid )
    {
        // In case the driver is registered at a GUCE level let's unregister it
        CString& driverName = static_cast< GUCEF::CORE::TCloneableString* >( eventdata )->GetData();
        UnregisterGUIDriver( driverName );
    }
    else
    if ( CORE::CGUCEApplication::VideoSetupCompletedEvent == eventid )
    {
        if ( !Init( CORE::CGUCEApplication::Instance()->GetPrimaryWindowContext() ) )
        {
            // If the GUI module is used the GUI initialization is considered critical.
            // Failure is a terminal error
            CORE::CGUCEApplication::Instance()->Stop();
        }
    }
    else
    if ( CORE::CGUCEApplication::VideoShutdownImminentEvent == eventid )
    {
        ShutdownGUISystems();
    }
}
void
CX11Window::SetText( const CString& text )
{GUCEF_TRACE;

    if ( NULL != m_display && 0 != m_window )
    {
        // We use the XTextProperty structure to store the title.
        ::XTextProperty windowName;
        windowName.value    = (unsigned char*) text.C_String();
        windowName.encoding = XA_STRING;
        windowName.format   = 8;
        windowName.nitems   = text.Length();

        // Tell X to ask the window manager to set the window title.
        // X11 itself doesn't provide window title functionality.
        ::XSetWMName( m_display, m_window, &windowName );
    }
}
Exemple #17
0
//+---------------------------------------------------------------
//
//  Member:     FatStream::Stat
//
//  Synopsis:   method of IStream interface
//
//----------------------------------------------------------------
STDMETHODIMP FatStream::Stat(STATSTG* pstatstg, DWORD grfStatFlag)
{
    HRESULT hr = S_OK;

    if(_hfile == INVALID_HANDLE_VALUE)
    {
        hr = E_FAIL;
        goto Cleanup;
    }

    if(pstatstg != NULL)
    {
        pstatstg->pwcsName = NULL;
        if(grfStatFlag != STATFLAG_NONAME)
        {
            int cchFileName = _cstrFileName.Length();
            if(cchFileName)
            {
                pstatstg->pwcsName = (LPOLESTR)CoTaskMemAlloc(sizeof(TCHAR)*(cchFileName+1));
                if(!pstatstg->pwcsName)
                {
                    hr = E_OUTOFMEMORY;
                    goto Cleanup;
                }
                _tcscpy(pstatstg->pwcsName, _cstrFileName);
            }
        }

        pstatstg->type = STGTY_STREAM;
        ULISet32(pstatstg->cbSize, (LONG)GetFileSize(_hfile, NULL));
        pstatstg->grfLocksSupported = 0; // no locking supported
    }

Cleanup:
    RRETURN (hr);
}
Exemple #18
0
//+---------------------------------------------------------------------------
//
//  Member:     CString::Set, public
//
//  Synopsis:   Allocates a string and initializes it
//
//  Arguments:  [cstr] -- String to initialize from
//
//----------------------------------------------------------------------------
HRESULT CString::Set(const CString& cstr)
{
    RRETURN(Set(cstr, cstr.Length()));
}
CEvent
CNotificationIDRegistry::Register( const CString& keyvalue                       ,
                                   const bool okIfAlreadyRegisterd /* = false */ )
{GUCEF_TRACE;

    m_dataLock.Lock();

    if ( keyvalue.Length() > 0 )
    {
        TRegistryList::const_iterator i = m_list.find( keyvalue );
        if ( i == m_list.end() )
        {
            if ( GUCEFCORE_UINT32MAX > m_lastid )
            {
                m_list[ keyvalue ] = m_lastid;
                ++m_lastid;
                m_dataLock.Unlock();

                GUCEF_SYSTEM_LOG( LOGLEVEL_NORMAL, "Event registered with ID " + UInt32ToString( m_lastid-1 ) + " and name \"" + keyvalue + "\"" );

                return CEvent( m_lastid-1, keyvalue );
            }

            /*
             *  Because all event id's have been used at least once we
             *  now have to perform a linear search for available event id's
             *  In practice it is rather unlikely this code will ever be used due to the insane
             *  amount of event registration actions required.
             */
            for ( UInt32 n=0; n<ULONG_MAX; ++n )
            {
                bool found = false;
                i = m_list.begin();
                while ( i != m_list.end() )
                {
                    if ( (*i).second == n )
                    {
                        found = true;
                        break;
                    }
                    ++i;
                }
                if ( !found )
                {
                    m_list[ keyvalue ] = n;
                    m_dataLock.Unlock();
                    return CEvent( n, keyvalue );
                }
            }
        }

        if ( !okIfAlreadyRegisterd )
        {
            m_dataLock.Unlock();
            GUCEF_EMSGTHROW( EKeyAlreadyRegistered, "CNotificationIDRegistry: Key is already registerd" );
        }
        m_dataLock.Unlock();
        return CEvent( (*i).second, keyvalue );
    }
    else
    {
        m_dataLock.Unlock();
        GUCEF_EMSGTHROW( EEmptyKeyString, "CNotificationIDRegistry: Empty key string" );
    }

    m_dataLock.Unlock();
}
bool
CIniParser::LoadFrom( CIOAccess& fileAccess )
{GUCEF_TRACE;

    // @TODO: take escape sequences into account
    if ( fileAccess.IsValid() )
    {
        bool isNewSection = true;
        CString sectionName;
        while ( !fileAccess.Eof() )
        {
            // Get the current line from the file, trimming white space on both ends
            CString line = fileAccess.ReadLine().Trim( true ).Trim( false );
            if( line.Length() > 0 )
            {
                // Get rid of any trailing commentary on this line
                Int32 commentaryIndex = line.HasChar( ';', false );
                if ( commentaryIndex > -1 )
                {
                    Int32 dummy = 0;
                    if ( !IsCharIndexWithinQuotes( line, commentaryIndex, dummy, dummy ) )
                    {
                        // we found a semicolon which is not contained within a quotation
                        // thus this is a commentary section which we should remove
                        line = line.CutChars( line.Length()-commentaryIndex, false ).Trim( false );
                    }
                }

                if( line.Length() > 0 )
                {
                    // Check if this is a section tag line
                    if ( ( line[ 0 ] == '[' ) && ( line[ line.Length()-1 ] == ']' ) )
                    {
                        sectionName = line.SubstrFromRange( 1, line.Length()-1 );
                        isNewSection = true;
                    }
                    else
                    {
                        Int32 equalsIndex = FindIndexOfNonQuotedEquals( line );
                        if ( equalsIndex > -1 )
                        {
                            // get the key and value strings
                            CString sectionBeforeEquals = StripQuotation( line.SubstrFromRange( 0, equalsIndex ) );
                            CString sectionAfterEquals = StripQuotation( line.SubstrFromRange( equalsIndex+1, line.Length() ) );

                            if ( ( sectionBeforeEquals.Length() > 0 ) &&
                                 ( sectionAfterEquals.Length() > 0 )   )
                            {
                                if ( isNewSection )
                                {
                                    TIniSection dummySection;
                                    m_iniData.push_back( dummySection );
                                    TIniSection& newSection = (*m_iniData.rbegin());
                                    newSection.sectionName = sectionName;
                                    newSection.sectionData.SetAllowDuplicates( true );
                                    newSection.sectionData.SetAllowMultipleValues( true );

                                    isNewSection = false;
                                }

                                TIniSection& newSection = (*m_iniData.rbegin());
                                newSection.sectionData.Set( sectionBeforeEquals, sectionAfterEquals );
                            }
                        }
                        // else:
                        // Line with junk on it we do not support
                        // we will try and be robust and ignore this line
                    }
                }
            }
        }
        return true;
    }
    return false;
}
Exemple #21
0
CDataNode::TDataNodeVector 
CDataNode::SearchForAll( const CString& query     ,
                         char seperator           ,
                         bool fromcurrent         ,
                         bool treatChildAsCurrent ) const
{GUCEF_TRACE;

    if ( fromcurrent )
    {
        CString thisname( query.SubstrToChar( seperator, true ) );
        if ( thisname == _name )
        {
            CString remnant( query.CutChars( thisname.Length()+1, true ) );
            if ( remnant.Length() > 0 )
            {            
                CString leftover;
                TDataNodeVector results = WalkTree( remnant   ,
                                                    seperator ,
                                                    leftover  );
                if ( 0 == leftover.Length() )
                {       
                    return results;
                }                                 
            }
            else
            {   
                // this node is the leaf node we are searching for
                TDataNodeVector result;
                result.push_back( const_cast< CDataNode* >( this ) );
                return result;
            }
        }
        else
        if ( treatChildAsCurrent )
        {
            TDataNodeVector results;
            TDataNodeList::const_iterator i = m_children.begin();
            while ( i != m_children.end()  )
            {
                TDataNodeVector childResults = (*i)->SearchForAll( query       ,
                                                                   seperator   ,
                                                                   fromcurrent ,
                                                                   false       );                
                TDataNodeVector::iterator n = childResults.begin();
                while ( n != childResults.end() )
                {
                    results.push_back( (*n) );
                    ++n;
                }
                ++i;
            }
            return results;
        }
        return TDataNodeVector();                                            
    }
    else
    {
        CString leftover;
        TDataNodeVector results = WalkTree( query     ,
                                            seperator ,
                                            leftover  );
        if ( 0 == leftover.Length() )
        {       
            return results;
        }
        return TDataNodeVector();
    }
}
Exemple #22
0
CDataNode::TDataNodeVector
CDataNode::WalkTreeImp( CString& sleftover ,
                        char seperator     ) const
{GUCEF_TRACE;
          
    if ( !m_children.empty() )
    {
        TDataNodeVector resultSet;                
        
        CDataNode* sn = (CDataNode*) this;       
        CString searchseg( sleftover.SubstrToChar( seperator, true ) );        
        CString left( sleftover.CutChars( searchseg.Length()+1, true ) );
        CString bestMatchLeftover( left );
                                                  
        CDataNode* n = m_children.front();                                                                                    
        while ( n )
        {
            // Are we looking for more nesting or a leaf node?
            if ( 0 == left.Length() )
            {
                // We are looking for a leaf node. Check if the current child matches
                if ( n->_name == searchseg )
                {
                    // nothing left to search for, so
                    // no point in continuing
                    resultSet.push_back( n );
                }        
            }
            else
            {            
                // check if this node could be a link in the search chain
                if ( n->_name == searchseg )
                {
                    // search the tree for our leftover
                    CString childLeftover = left;
                    TDataNodeVector childResultSet = n->WalkTreeImp( childLeftover, seperator );
                        
                    // if what we found is better then what we found so far then
                    // substitute the current deepest nodes with the new deeper nodes.
                    if ( bestMatchLeftover.Length() > childLeftover.Length() )                  
                    {
                        // We found a better match, switch to that one
                        resultSet = childResultSet;
                        bestMatchLeftover = childLeftover;
                    }
                    else
                    if ( bestMatchLeftover.Length() == childLeftover.Length() )
                    {
                        // We found more equally good matches
                        TDataNodeVector::iterator m = childResultSet.begin();
                        while ( m != childResultSet.end() )
                        {
                            resultSet.push_back( (*m) );
                            ++m;
                        }
                    }
                }
            }
            n = n->_pnext;
        }

        if ( !resultSet.empty() )
            sleftover = bestMatchLeftover;
        return resultSet;
    }
    
    TDataNodeVector resultSet;
    resultSet.push_back( const_cast<CDataNode*>( this ) );
    return resultSet;                                                                          
}                     
Exemple #23
0
 int CString::Compare(const CString& str) const {
   return Compare(str.Str(), str.Length());
 }
bool
CIniParser::IsCharIndexWithinQuotes( const CString& testString  ,
                                     UInt32 charIndex           ,
                                     Int32& quotationStartIndex ,
                                     Int32& quotationEndIndex   )
{GUCEF_TRACE;

    // initial sanity check
    if ( charIndex+1 >= testString.Length() ) return false;

    // go through string identifying quoted sections as we go and checking whether
    // this encompasses the char given
    Int32 quoteIndex = -1;
    bool firstQuoteFound = false;
    bool quoteFound = false;
    for ( UInt32 i=0; i<testString.Length(); ++i )
    {
        if ( i >= charIndex && !firstQuoteFound )
        {
            // there was no quotation char until now and we are at
            // the search char thus it logically cannot be between quotes
            quotationStartIndex = -1;
            quotationEndIndex = -1;
            return false;
        }

        if ( testString[ i ] == '\"' )
        {
            if ( !firstQuoteFound )
            {
                firstQuoteFound = true;
            }

            if ( !quoteFound )
            {
                if ( i > charIndex )
                {
                    // We went beyond the search char yet no opening quote
                    // was found this this char is not within a quoted section
                    quotationStartIndex = -1;
                    quotationEndIndex = -1;
                    return false;
                }
                quoteFound = true;
                quoteIndex = i;
            }
            else
            {
                // this is a closing quote
                if ( i > charIndex )
                {
                    // this is an enclosing quotation section
                    quotationStartIndex = quoteIndex;
                    quotationEndIndex = i;
                    return true;
                }
                quoteFound = false;
            }
        }
    }
    return false;
}
bool
CIniParser::SaveTo( CDataNode& rootNode ) const
{GUCEF_TRACE;

    TIniData::const_iterator i = m_iniData.begin();
    while ( i != m_iniData.end() )
    {
        const TIniSection& iniSection = (*i);
        const CValueList& sectionData = iniSection.sectionData;

        CString nodeName = iniSection.sectionName.SubstrToChar( '\\', false );
        CString sectionName;

        if ( nodeName.Length()+1 < iniSection.sectionName.Length() )
        {
            sectionName = iniSection.sectionName.CutChars( nodeName.Length()+1, false );
        }

        // We use the ordering in the ini of the different sections to implicitly denote going up and down
        // a tree thus allowing branches to be defined in an ini file which otherwise does not support this concept
        CDataNode* sectionNodeParent = NULL;
        if ( !sectionName.IsNULLOrEmpty() )
        {
            CDataNode::TDataNodeVector existingPaths = rootNode.SearchForAll( sectionName, '\\', true, true );
            if ( !existingPaths.empty() )
            {
                sectionNodeParent = *existingPaths.rbegin();
            }
            else
            {
                sectionNodeParent = rootNode.Structure( sectionName, '\\' );
            }
        }
        else
        {
            sectionNodeParent = &rootNode;
        }

        // Make a new child node symbolizing the end of the sequence of the section name
        // for example [My/New/Sequence] as a section name in the ini would result in
        // the whole sequence creates as nodes with Sequence being the parent node
        // where we add the key/value pairs from the ini section
        CDataNode* sectionNode = sectionNodeParent->AddChild( nodeName );

        CValueList::TValueMap::const_iterator n = sectionData.GetDataBeginIterator();
        while ( n != sectionData.GetDataEndIterator() )
        {
            const CString& key = (*n).first;
            const CValueList::TStringVector& values = (*n).second;

            // Since key/value pairs in an ini section have no uniqueness constraint we cannot
            // set the pairs as attributes. Instead they are child nodes using the simplistic value representation
            CValueList::TStringVector::const_iterator m = values.begin();
            while ( m != values.end() )
            {
                CDataNode* keyValueNode = sectionNode->AddChild( key );
                keyValueNode->SetValue( (*m) );

                ++m;
            }
            ++n;
        }
        ++i;
    }
    return true;
}
XSI::CStatus CAxisInterpOp::Init(UpdateContext& ctx, long )
{
	// clean up
	if ( m_aWeights )
		delete []m_aWeights;
	if ( m_aTriggerTol )
		delete []m_aTriggerTol;
	if ( m_aTriggerOri )
		delete []m_aTriggerOri;
	if ( m_aTargetOri )
		delete []m_aTargetOri;
	if ( m_aTargetPos )
		delete []m_aTargetPos;
	m_cTriggers = 0;

	static const wchar_t* wcsTriggerTag = L"<trigger> ";

	wchar_t* startpos = (wchar_t*)m_csTriggers.GetWideString();
	if ( !startpos )  // no triggers defined
		return( CStatus::Fail );

	wchar_t* endpos = startpos + m_csTriggers.Length(); 

	// allocate memory
	unsigned long cBuffSize(10);

	m_aWeights = new double[cBuffSize]; 
	::memset( m_aWeights, 0, sizeof(double)*cBuffSize );
	m_aTriggerTol = new double[cBuffSize];
	::memset( m_aTriggerTol, 0, sizeof(double)*cBuffSize );
	m_aTriggerOri = new double[cBuffSize*3];
	::memset( m_aTriggerOri, 0, sizeof(double)*cBuffSize*3 );
	m_aTargetOri = new double[cBuffSize*3];
	::memset( m_aTargetOri, 0, sizeof(double)*cBuffSize*3 );
	m_aTargetPos = new double[cBuffSize*3];
	::memset( m_aTargetPos, 0, sizeof(double)*cBuffSize*3 );

	// ParseHelperEntry
	wchar_t* nexttrigger = ::wcsstr( startpos, wcsTriggerTag);

	while ( nexttrigger < endpos && nexttrigger != 0 && m_cTriggers<cBuffSize ) {

		::swscanf( nexttrigger,
			L"<trigger> %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", 
			&m_aTriggerTol[m_cTriggers],

			&m_aTriggerOri[(m_cTriggers*3)+0],
			&m_aTriggerOri[(m_cTriggers*3)+1],
			&m_aTriggerOri[(m_cTriggers*3)+2],

			&m_aTargetOri[(m_cTriggers*3)+0],
			&m_aTargetOri[(m_cTriggers*3)+1],
			&m_aTargetOri[(m_cTriggers*3)+2],

			&m_aTargetPos[(m_cTriggers*3)+0],
			&m_aTargetPos[(m_cTriggers*3)+1],
			&m_aTargetPos[(m_cTriggers*3)+2]
			);

		m_cTriggers++;
		
		nexttrigger = ::wcsstr( nexttrigger+1, wcsTriggerTag);
	};

	
	return CStatus::OK;
}