Example #1
0
bool mqtt_async::MqttClient::Publish(const std::string& topic, const void* payload,  INT32 len, int qos,  int retained/*default=0*/, const ActDoneCB& cb)    
{
    MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
    Token* tok = nullptr;
    std::shared_ptr<Token> stok;
    TRACE("mqtt_async::MqttClient::Publish");
    if (cb)
    {
        TRACE("mqtt_async::MqttClient::Publish  with  callback");
        tok = new Token(this);
        stok = std::shared_ptr<Token>(tok);
        stok->act_done_cb = cb;
        SaveToken(stok);
    }

    opts.onSuccess = cb?&Token::OnSuccess : nullptr ;
    opts.onFailure =   cb?&Token::OnFailed : nullptr ;
    opts.context = tok;
    MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
    pubmsg.payload = const_cast<void*>(payload);
    pubmsg.payloadlen =  len;
    pubmsg.qos = qos; 
    pubmsg.retained = retained;

    int rc = MQTTAsync_sendMessage(client, (char*)topic.c_str(), &pubmsg, &opts) ;
     if (rc != MQTTASYNC_SUCCESS)  
     {
         if (tok)
            RemoveToken(tok);

        TRACE("mqtt_async::MqttClient::Publish   return false");    
        return false;
     }  
     return true;    
}   
void TokenTree::RemoveToken(int idx)
{
    if (idx<0 || (size_t)idx >= m_Tokens.size())
        return;

    RemoveToken(m_Tokens[idx]);
}
Example #3
0
bool mqtt_async::MqttClient::Subscribe(string topic, int qos, const ActDoneCB& cb) 
{
    MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;    
    Token* tok = nullptr;
    std::shared_ptr<Token> stok;
    if (cb)
    {
        tok = new Token(this);
        stok = std::shared_ptr<Token>(tok);
        stok->act_done_cb = cb;
        SaveToken(stok);
    }

    opts.onSuccess = cb?&Token::OnSuccess : nullptr ;
    opts.onFailure =   cb?&Token::OnFailed : nullptr ;
    opts.context = tok;
    int rc;
    if ((rc = MQTTAsync_subscribe(client,  topic.c_str(),  qos, &opts)) != MQTTASYNC_SUCCESS)
    {
        if (tok)
            RemoveToken(tok);
        return false;
    }       
    return true;     
}
Example #4
0
bool mqtt_async::MqttClient::Disconnect(int tmout, const ActDoneCB& cb) 
{
    MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
    Token* tok =  nullptr;
    std::shared_ptr<Token> stok;
    if (cb)
    {
        tok = new Token(this);
        stok = std::shared_ptr<Token>(tok);
        stok->act_done_cb = cb;
        SaveToken(stok);
    }

    opts.onSuccess = cb?&Token::OnSuccess : nullptr ;
    opts.onFailure =   cb?&Token::OnFailed : nullptr ;
    opts.timeout = tmout;
    opts.context = tok;

    int rc;
    if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS)
    {
        if (tok)
            RemoveToken(tok);
        throw rc;
    }        
    return true;    
}
Example #5
0
int TokensTree::erase(int loc)
{
    if(!m_Tokens[loc])
        return 0;
    RemoveToken(loc);
    return 1;
}
Example #6
0
UPnpCDSExtensionResults *UPnpCDSExtension::ProcessItem( UPnpCDSRequest          *pRequest,
                                                        UPnpCDSExtensionResults *pResults,
                                                        QStringList             &idPath )
{
    pResults->m_nTotalMatches   = 0;
    pResults->m_nUpdateID       = 1;

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------
   // VERBOSE(VB_UPNP, QString("UPnpCDSExtension::ProcessItem : %1").arg(idPath
    switch( pRequest->m_eBrowseFlag )
    {
	case CDS_BrowseMetadata:
        {
            // --------------------------------------------------------------
            // Return 1 Item
            // --------------------------------------------------------------

            QStringMap  mapParams;
            QString     sParams = idPath.last().section( '?', 1, 1 );
            sParams.replace(QRegExp( "&amp;"), "&" );

            HTTPRequest::GetParameters( sParams, mapParams );

            MSqlQuery query(MSqlQuery::InitCon());

            if (query.isConnected())
            {
                BuildItemQuery( query, mapParams );

                query.exec();

                if (query.isActive() && query.size() > 0)
                {
                    if ( query.next() )
                    {
                        pRequest->m_sObjectId = RemoveToken( "/", pRequest->m_sObjectId, 1 );

                        AddItem( pRequest->m_sObjectId, pResults, false, query );
                        pResults->m_nTotalMatches = 1;
                    }
                }
            }
            break;
        }
        case CDS_BrowseDirectChildren:
        {
            // Items don't have any children.
            break;
        }

    }

    return pResults;
}
Example #7
0
void TokensTree::FreeTemporaries()
{
    int i;
    for(i = m_Tokens.size() -1;i >= 0;i--)
    {
        Token* token = m_Tokens[i];
        if (token && token->m_IsTemp)
            RemoveToken(token);
    }
}
void TokenTree::RemoveFile(int fileIdx)
{
    if (fileIdx <= 0) return; // nothing to do

    TokenIdxSet& the_list = m_FileMap[fileIdx];
    for (TokenIdxSet::const_iterator it = the_list.begin(); it != the_list.end();)
    {
        int idx = *it;
        if (idx < 0 || (size_t)idx > m_Tokens.size())
        {
            the_list.erase(it++);
            continue;
        }

        Token* the_token = at(idx);
        if (!the_token)
        {
            the_list.erase(it++);
            continue;
        }

        // do not remove token lightly...
        // only if both its decl filename and impl filename are either empty or match this file
        // if one of those filenames do not match the above criteria
        // just clear the relevant info, leaving the token where it is...
        bool match1 = the_token->m_FileIdx     == 0 || static_cast<int>(the_token->m_FileIdx)     == fileIdx;
        bool match2 = the_token->m_ImplFileIdx == 0 || static_cast<int>(the_token->m_ImplFileIdx) == fileIdx;
        bool match3 = CheckChildRemove(the_token, fileIdx);
        if (match1 && match2 && match3)
        {
            RemoveToken(the_token); // safe to remove the token
            the_list.erase(it++);
            continue;
        }
        else
        {
            // do not remove token, just clear the matching info
            if (match1)
            {
                the_token->m_FileIdx = 0;
                the_token->m_Line = 0;
            }
            else if (match2)
            {
                the_token->m_ImplFileIdx = 0;
                the_token->m_ImplLine = 0;
            }
        }

        ++it;
    }
}
Example #9
0
bool mqtt_async::MqttClient::Connect(int interval,  const ActDoneCB& cb) 
{
    int rc;
    if (!monitor_init)
    {
        MQTTAsync_connectionLost* cl = monitor.conn_lost_cb? &Monitor::ConnectionLost : nullptr;
        MQTTAsync_messageArrived* ma = monitor.msg_recv_cb? &Monitor::MsgRecv : nullptr;
        MQTTAsync_deliveryComplete* dc =  monitor.delivery_done_cb ?  &Monitor::Delivered : nullptr;         
        rc = MQTTAsync_setCallbacks(client,  &monitor,  cl, ma, dc);
        if (rc != MQTTASYNC_SUCCESS)
            throw rc;    
        monitor_init = true;          
    }


    MQTTAsync_connectOptions opts = MQTTAsync_connectOptions_initializer;
    opts.keepAliveInterval = interval;
    opts.cleansession = 1;

    Token* tok = nullptr;
    std::shared_ptr<Token> stok;
    if (cb)
    {
        tok = new Token(this);
        stok = std::shared_ptr<Token>(tok);
        stok->act_done_cb = cb;
        SaveToken(stok);
    }

    opts.onSuccess = cb?&Token::OnSuccess : nullptr ;
    opts.onFailure =   cb?&Token::OnFailed : nullptr ;
    opts.context = tok;
    
    if ((rc = MQTTAsync_connect(client, &opts)) != MQTTASYNC_SUCCESS)
    {
        if (tok)
            RemoveToken(tok);
        throw rc;
    }      
    return true;     
}
Example #10
0
void TokensTree::RemoveFile(int index)
{
    if(index <=0)
        return;
    TokenIdxSet& the_list = m_FilesMap[index];
    TokenIdxSet::iterator it;
    for(it = the_list.begin(); it != the_list.end();it++)
    {
        int idx = *it;
        if(idx < 0 || (size_t)idx > m_Tokens.size())
            continue;
        Token* the_token = at(idx);
        if(!the_token)
            continue;

        // do not remove token lightly...
        // only if both its decl filename and impl filename are either empty or match this file
        // if one of those filenames do not match the above criteria
        // just clear the relevant info, leaving the token where it is...

        bool match1 = the_token->m_File == 0 || (int)the_token->m_File == index;
        bool match2 = the_token->m_ImplFile == 0 || (int)the_token->m_ImplFile == index;
        if (match1 && match2)
            RemoveToken(the_token); // safe to remove the token
        else
        {
            // do not remove token, just clear the matching info
            if (match1)
            {
                the_token->m_File = 0;
                the_token->m_Line = 0;
            }
            else if (match2)
            {
                the_token->m_ImplFile = 0;
                the_token->m_ImplLine = 0;
            }
        }
    }
    the_list.clear();
}
Example #11
0
UPnpCDSExtensionResults *UPnpCDSExtension::ProcessKey( UPnpCDSRequest          *pRequest,
                                                       UPnpCDSExtensionResults *pResults,
                                                       QStringList             &idPath )
{
    pResults->m_nTotalMatches   = 0;
    pResults->m_nUpdateID       = 1;

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    QString sKey = idPath.last().section( '=', 1, 1 );
    QUrl::decode( sKey );

    if (sKey.length() > 0)
    {
        int nNodeIdx = idPath[ idPath.count() - 2 ].toInt();

        switch( pRequest->m_eBrowseFlag )
        {

            case CDS_BrowseMetadata:
            {
                UPnpCDSRootInfo *pInfo = GetRootInfo( nNodeIdx );

                if (pInfo == NULL)
                    return pResults;

                pRequest->m_sParentId = RemoveToken( "/", pRequest->m_sObjectId, 1 );

                // --------------------------------------------------------------
                // Since Key is not always the title, we need to lookup title.
                // --------------------------------------------------------------

                MSqlQuery query(MSqlQuery::InitCon());

                if (query.isConnected())
                {
                    QString sSQL   = QString( pInfo->sql )
                                        .arg( pInfo->where );

                    // -=>TODO: There is a problem when called for an Item, instead of a container
                    //          sKey = '<KeyName>/item?ChanId' which is incorrect.


                    query.prepare  ( sSQL );
                    query.bindValue( ":KEY", sKey );
                    query.exec();

                    if (query.isActive() && query.size() > 0)
                    {
                        if ( query.next() )
                        {
                            // ----------------------------------------------
                            // Return Container Object Only
                            // ----------------------------------------------

                            pResults->m_nTotalMatches   = 1;
                            pResults->m_nUpdateID       = 1;

                            CDSObject *pItem = CreateContainer( pRequest->m_sObjectId,
                                                                query.value(1).toString(),
                                                                pRequest->m_sParentId );

                            pItem->SetChildCount( GetDistinctCount( pInfo ));

                            pResults->Add( pItem );
                        }
                    }
                }
                break;
            }

            case CDS_BrowseDirectChildren:
            {

                CreateItems( pRequest, pResults, nNodeIdx, sKey, true );

                break;
            }

            case CDS_BrowseUnknown:
                default:
                break;
        }
    }

    return pResults;
}
Example #12
0
bool CParser::ReadNextLine (std::ifstream& FileInput, int& nLineNum, 
			    std::string& szInputString, const int MAXCHARS,
			    const std::string& szComment, bool bLowerCase)
// ---------------------------------------------------------------------------
// Function: reads the next line skipping over the comment lines
//           and converts all alphabets to lower case if requested
// Input:    file istream, line #, string to hold the input line,
//           max. # of characters expected in each input line,
//           comment character(s) at the beginning of a comment line,
//           lowercase conversion option
// Output:   updated values of line # and the string
//           return value is true if successful
//                           false if an error state is encountered
// Restriction: Cannot read a line over 256 characters
// ---------------------------------------------------------------------------
{
  int flag = 0;
  int flag1 =0;
  bool bWhSpc = false;
  int tokenfound = 1;
  const int MAXCH = 1000;
  char szInp[MAXCH];
  char szTemp [MAXCH];
  std::vector<std::string> tokens;

  // enough capacity to read and store?
  if (MAXCHARS > MAXCH)
    return false;

  // comment character(s)
  int nCLen = static_cast<int>(szComment.length());
  // read the line (skip over comment lines)
  for(;;)
    {
      ++nLineNum;
      FileInput.getline (szInp, MAXCHARS);
      //       // end-of-file?
      //       if (FileInput.eof())
      // 	return false;
      if (FileInput.fail())
	FileInput.clear (FileInput.rdstate() & ~std::ios::failbit);
      // unrecoverable error?
      if (FileInput.bad())
	return false;

      // successful read
      szInputString = szInp;
      GetTokens(szInputString, " ", tokens);
      bWhSpc = EatWhiteSpace(szInputString);
      if ((szInputString.substr(0,nCLen) != szComment)&& (bWhSpc ==false)){	   
	szInputString = szInp;
	GetTokens(szInputString, " ", tokens);
	for(int i=0; i< abs(tokens.size()); i++){
	  std::string temptoken = tokens[i];
	  if (temptoken == "&")
	    flag1 = 1;
	}

	//Filter the comment tokens
	//  FilterComment(szInputString, szComment);

	//if "&" is found continue to read the next line      
	std::string szTempString = szInputString;

	// check if line is continued &
	while(flag1 ==1 && tokenfound == 1){	
	  GetTokens(szTempString, " ", tokens);
	  for(int i=1; i<=abs(tokens.size()); i++){
	    std::string temptoken = tokens[i-1];
	    if (temptoken == "&"){
	      tokenfound = 1;
	      flag = 1;
	    }
	    else{
	      if(flag==1)
		flag = 1;//do nothing token already found
	      else
		tokenfound = 0;
	    }
	  }
	  if(tokenfound ==1){
	    ++nLineNum;
	    RemoveToken(szInputString);
	    //- getting more tokens and add to the existing 
	    FileInput.getline (szTemp, MAXCHARS);
	    // end-of-file?
	    if (FileInput.eof())
	      return false;
	    if (FileInput.fail())
	      FileInput.clear (FileInput.rdstate() & ~std::ios::failbit);
	    // unrecoverable error?
	    if (FileInput.bad())
	      return false;
	    // successful read 
	    szTempString = szTemp;
	    FilterComment(szTempString, szComment);
	    szInputString+=" ";
	    szInputString+=szTemp;
	  }
	  else{
	    break;//while loop ents
	  }
	  flag = 0;
	}
	// while loop ends
	// convert to lower case?
	if (bLowerCase){
	  for (int i=0; i < static_cast<int>(szInputString.length()); i++)
	    szInputString[i] = tolower(szInputString[i]);
	}
	break;
      }
    }
  return true;
}
Example #13
0
/*********************************************************************
 * Function: FormatManPage
 *
 *    FormatManPage is the top entry point for formating man pages
 *	into a form understood by a display area.
 *
 *********************************************************************/
static	int
FormatManPage(
	VarHandle	  my_vars,
	BufFilePtr	  in_file,
	char		 *in_buf,
	int		  in_size,
	_DtHelpFontHints	*font_attr,
	char		**out_buf,
	int		 *out_size,
	int		 *out_max )
{
    int		 italicCnt = 0;
    int		 result = 0;
    int		 cread;
    int		 lastLen;
    int		 checkLen;
    int		 retWCLen;
    wchar_t	 lastWC;
    wchar_t	 retWC;
    char	*rloc = in_buf;
    char	*retStrPtr;
    char	 c;
    char	 retC;
    Boolean      flag = False;
    enum State	 newState;
    enum State	 state = Char;

    cread = strlen (rloc);

    do
      {
	/*
	 * while I can read information process; loop.
	 */
	while (result != -1 && cread > 0)
	  {
	    /**
	     * check for the size of the character
	     **/
	    checkLen = mblen(rloc, MB_CUR_MAX);

	    /*
	     * if we hit a null character before we've run out of characters,
	     * we've got corrupt data.
	     */
	    if (checkLen == 0)
		return -1;

	    if (checkLen > 0)
	      {
		/*
		 * check for end of line
		 */
		if (checkLen == 1 && *rloc == '\n')
		  {
		    cread--;
		    if (state == Bold || state == Italic)
		        result = WriteToken(EndToken, EndTokenSize,
						out_buf, out_size, out_max);

		    if (result != -1)
		        result = _DtHelpCeAddCharToBuf (&rloc, out_buf,
						out_size, out_max, 128);
		    if (result != -1)
		      {
		        result = __DtHelpCeProcessString(
					my_vars, NULL,
					_DtCvLITERAL,
					ScanString,
					*out_buf,
					*out_size,
					0,
					False,
					font_attr);
		        *out_size = 0;
		        (*out_buf)[0] = '\0';
		        state = Char;
		      }
		  }
		else
		  {
		    switch (state)
		      {
			case Char:
			case BoldDone:
			case BoldItalicDone:
				/*
				 * get the character and wide character
				 * representation of the next character.
				 */
				c        = *rloc;
				lastLen  = mbtowc (&lastWC, rloc, MB_CUR_MAX);

				/*
				 * skip past this character.
				 */
				rloc     = rloc  + lastLen;
				cread    = cread - lastLen;

				/*
				 * Check ahead for bold or italic sequences
				 */
				newState = GetNextState (c, lastWC, lastLen,
						rloc,
						&retC, &retWC, &retWCLen,
						&retStrPtr, &flag);

				if (newState == Bold)
				  {
				    if (state == BoldDone)
					RemoveToken(EndTokenSize, out_buf, out_size);
				    else
					result = WriteToken(BoldToken,
							BoldTokenSize,
							out_buf, out_size,
							out_max);

				    /*
				     * skip the backspaces and the extra
				     * copy of the character.
				     */
				    cread = cread - (retStrPtr - rloc);
				    rloc  = retStrPtr;
				  }
				else if (newState == Italic)
				  {
				    if (state != BoldItalicDone)
					result = WriteToken(ItalicToken,
							ItalicTokenSize,
							out_buf, out_size,
							out_max);

				    /*
				     * skip the blanks after the current
				     * character plus the character after
				     * that. The returned wide character
				     * is the character that is to be
				     * italicized.
				     */
				    cread   = cread - (retStrPtr - rloc);
				    rloc    = retStrPtr;
				    c       = retC;
				    lastWC  = retWC;
				    lastLen = retWCLen;
				    italicCnt = 1;

				    if (state == BoldItalicDone &&
					GetNextState (c, lastWC, lastLen, rloc,
						&retC, &retWC, &retWCLen,
						&retStrPtr, &flag) == Bold)
				      {
					RemoveToken(EndTokenSize, out_buf, out_size);
					newState = BoldItalic;
				      }
				  }
				else if (state == BoldItalicDone)
				    result = WriteToken(EndToken, EndTokenSize,
							out_buf, out_size,
							out_max);

				state = newState;


				result = WriteOutChar(lastLen, lastWC, c,
						out_buf, out_size, out_max, flag);
				break;

			case BoldItalic:
			case Bold:
				if (GetNextState (c, lastWC, lastLen, rloc,
						&retC, &retWC, &retWCLen,
						&retStrPtr, &flag) == Bold)
				  {
				  /* skip backspaces and copy characters */
				    cread = cread - (retStrPtr - rloc);
				    rloc  = retStrPtr;
				  }
				else
				  {
				    result = WriteToken(EndToken, EndTokenSize,
						out_buf, out_size, out_max);
				    if (state == BoldItalic)
				        state = BoldItalicDone;
				    else
				        state = BoldDone;
				  }
				break;

			case Italic:
				c = *rloc;
				newState = GetNextState (c, lastWC, lastLen,
						rloc,
						&retC, &retWC, &retWCLen,
						&retStrPtr, &flag);

				if (newState == Italic)
				  {
				    italicCnt++;
				    cread   = cread - (retStrPtr - rloc);
				    rloc    = retStrPtr;
				    c       = retC;
				    lastWC  = retWC;
				    lastLen = retWCLen;

				    result = WriteOutChar(lastLen, lastWC, c,
						out_buf, out_size, out_max, flag);
				  }
				else if (italicCnt == 1 && lastWC == retWC
						&& newState == Bold)
				  {
				    RemoveToken(lastLen, out_buf, out_size);

				    result  = WriteToken(BoldToken,
							BoldTokenSize,
							out_buf, out_size,
							out_max);

				    cread   = cread - (retStrPtr - rloc);
				    rloc    = retStrPtr;
				    c       = retC;
				    lastWC  = retWC;
				    lastLen = retWCLen;

				    result = WriteOutChar(lastLen, lastWC, c,
						out_buf, out_size, out_max, flag);

				    state = BoldItalic;
				  }
				else
				  {
				    result    = WriteToken(EndToken,
							EndTokenSize,
							out_buf, out_size,
							out_max);
				    state     = Char;
				    italicCnt = 0;
				  }

				break;
		      }
		  }

		if (cread < (3 * ((int) MB_CUR_MAX)) &&
						!feof (FileStream(in_file)))
		    cread = 0;
	      }
	    else
	      {
		/**
		 * if it is an invalid character - skip.
		 * But be careful.
		 * If this is the start of a multi-byte character,
		 * I must save it and try again on the next read.
		 **/
		if (cread < ((int) MB_CUR_MAX))
		    cread = 0;
		else
		  {
		    /*
		     * otherwise we've got corrupt data.
		     */
		    return -1;
		  }
	      }
          }
	if (result != -1 && !feof(FileStream(in_file)))
	  {
	    if (_DtHelpCeGetNxtBuf (in_file, in_buf, &rloc, in_size) == -1)
		result = -1;

	    if (result != -1)
	        cread = strlen (rloc);
	  }
      } while (result != -1 && cread > 0);

    return(result);

} /* End FormatManPage */
void TokenTree::RemoveToken(Token* oldToken)
{
    if (!oldToken)
        return;

    int idx = oldToken->m_Index;
    if (m_Tokens[idx]!=oldToken)
        return;

    // Step 1: Detach token from its parent

    Token* parentToken = 0;
    if ((size_t)(oldToken->m_ParentIndex) >= m_Tokens.size())
        oldToken->m_ParentIndex = -1;
    if (oldToken->m_ParentIndex >= 0)
        parentToken = m_Tokens[oldToken->m_ParentIndex];
    if (parentToken)
        parentToken->m_Children.erase(idx);

    TokenIdxSet nodes;
    TokenIdxSet::const_iterator it;

    // Step 2: Detach token from its ancestors

    nodes = (oldToken->m_DirectAncestors);
    for (it = nodes.begin();it!=nodes.end(); ++it)
    {
        int ancestoridx = *it;
        if (ancestoridx < 0 || (size_t)ancestoridx >= m_Tokens.size())
            continue;
        Token* ancestor = m_Tokens[ancestoridx];
        if (ancestor)
            ancestor->m_Descendants.erase(idx);
    }
    oldToken->m_Ancestors.clear();
    oldToken->m_DirectAncestors.clear();

    // Step 3: Remove children

    nodes = (oldToken->m_Children); // Copy the list to avoid interference
    for (it = nodes.begin();it!=nodes.end(); ++it)
        RemoveToken(*it);
    // m_Children SHOULD be empty by now - but clear anyway.
    oldToken->m_Children.clear();

    // Step 4: Remove descendants

    nodes = oldToken->m_Descendants; // Copy the list to avoid interference
    for (it = nodes.begin();it!=nodes.end(); ++it)
    {
        if (*it == idx) // that should not happen, we can not be our own descendant, but in fact that can happen with boost
        {
            CCLogger::Get()->DebugLog(_T("Break out the loop to remove descendants, to avoid a crash. We can not be our own descendant!"));
            break;
        }
        RemoveToken(*it);
    }
    // m_Descendants SHOULD be empty by now - but clear anyway.
    oldToken->m_Descendants.clear();

    // Step 5: Detach token from the SearchTrees

    int idx2 = m_Tree.GetItemNo(oldToken->m_Name);
    if (idx2)
    {
        TokenIdxSet& curList = m_Tree.GetItemAtPos(idx2);
        curList.erase(idx);
    }

    // Now, from the global namespace (if applicable)
    if (oldToken->m_ParentIndex == -1)
    {
        m_GlobalNameSpaces.erase(idx);
        m_TopNameSpaces.erase(idx);
    }

    // Step 6: Delete documentation associated with removed token

    m_TokenDocumentationMap.erase(oldToken->m_Index);

    // Step 7: Finally, remove it from the list.

    RemoveTokenFromList(idx);
}
void TokenTree::erase(Token* oldToken)
{
    RemoveToken(oldToken);
}
Example #16
0
void TokensTree::RemoveToken(Token* oldToken)
{
    if(!oldToken)
        return;
    int idx = oldToken->m_Self;
    if(m_Tokens[idx]!=oldToken)
        return;

    // Step 1: Detach token from its parent

    Token* parentToken = 0;
    if((size_t)(oldToken->m_ParentIndex) >= m_Tokens.size())
        oldToken->m_ParentIndex = -1;
    if(oldToken->m_ParentIndex >= 0)
        parentToken = m_Tokens[oldToken->m_ParentIndex];
    if(parentToken)
        parentToken->m_Children.erase(idx);

    TokenIdxSet nodes;
    TokenIdxSet::iterator it;

    // Step 2: Detach token from its ancestors
    nodes = (oldToken->m_DirectAncestors);
    for(it = nodes.begin();it!=nodes.end(); it++)
    {
        int ancestoridx = *it;
        if(ancestoridx < 0 || (size_t)ancestoridx >= m_Tokens.size())
            continue;
        Token* ancestor = m_Tokens[ancestoridx];
        if(ancestor)
            ancestor->m_Descendants.erase(idx);
    }
    oldToken->m_Ancestors.clear();
    oldToken->m_DirectAncestors.clear();

    // Step 3: Remove children
    nodes = (oldToken->m_Children); // Copy the list to avoid interference
    for(it = nodes.begin();it!=nodes.end(); it++)
        RemoveToken(*it);
    // m_Children SHOULD be empty by now - but clear anyway.
    oldToken->m_Children.clear();

    // Step 4: Remove descendants
    nodes = oldToken->m_Descendants; // Copy the list to avoid interference
    for(it = nodes.begin();it!=nodes.end(); it++)
        RemoveToken(*it);
    // m_Descendants SHOULD be empty by now - but clear anyway.
    oldToken->m_Descendants.clear();

    // Step 5: Detach token from the SearchTrees
    int idx2 = m_Tree.GetItemNo(oldToken->m_Name);
    if(idx2)
    {
        TokenIdxSet& curlist = m_Tree.GetItemAtPos(idx2);
        curlist.erase(idx);
    }

    // Now, from the global namespace (if applicable)
    if(oldToken->m_ParentIndex == -1)
    {
        m_GlobalNameSpace.erase(idx);
        m_TopNameSpaces.erase(idx);
    }

    // Step 6: Finally, remove it from the list.
    RemoveTokenFromList(idx);
}