Starlib: example 2

(Deleting something)

This example shows how to delete something.

Let's assume that you have already read a STAR file into memory using yyparse() as shown in the main example. This star file is pointed to by the variable called AST

To delete something you must first get a pointer to it via one of the searching techniques, then you delete that pointer. It's that simple. Almost.

The destructors for the various nodes are set up to automatically remove a node from its parent when it gets deleted via the delete operator. So to delete a DataItemNode, simply use the delete operator on it. To delete a save frame, get a pointer to it and use the delete operator on it.

The place where this idea breaks down is where deleting something causes descrepencies to appear in the STAR tree. For example, it makes no sense to delete a single DataValueNode from inside a loop, leaving a "hole". Therefore, it is sometimes dangerous to delete something directly from a star file tree. The table below should help sort things out.

The following is a list of types of nodes where it is safe to use the delete operator directly to delete a node:
Node Type Effect of deleting
BlockNode OK Deletes the Block Node properly.
DataBlockNode OK Deletes the BLock Node properly.
DataFileNode Not defined.
DataHeadingNode Do not delete. Deleting a Heading for a data node without deleting the datanode itself is meaningless.
DataItemNode OK Deletes the DataItemNode from the save frame or data block or global block that it is inside.
DataListNode Do not delete. Deleting a DataListNode without also deleting the block it is inside of is meaningless.
DataLoopDefListNode Do not delete. Deleting a DataLoopDefListNode without also deleting the loop it is inside of is meaningless.
DataLoopNode OK Deletes the loop from the save frame or data block or global block that it is inside of.
DataLoopValListNode Do not Delete. Deleting a data loop val list without also deleting the loop it is inside of is meaningless.
DataNameNode Do Not Delete. Deleting a data name from inside of a loop or a data item is meaningless. But note, however, that DataLoopNode does have a function called RemoveColumn(), if removing the entire column under the tag as well as the tag is what is desired.
DataNode N/A There is no such thing as a node that is a DataNode. DataNode is a pure virtual class, from which are derived DataItemNode, DataLoopNode, and SaveFrameNode.
DataValueNode Do not Delete. Deleting a data value without deleting the item or loop it is inside of is meaningless.
GlobalBlockNode OK Deleting a GlobalBlockNode deletes everything inside it.
GlobalHeadingNode Do Not Delete. Deleting a heading without deleting the thing it labels is meaningless.
HeadingNode Do Not Delete. Deleting a heading without deleting the thing it labels is meaningless.
LoopDefListNode Do Not Delete. Deleting a LoopDefListNode without deleting the loop it is inside of is meaningless.
SaveFrameListNode Do Not Delete. Deleting a SaveFrameListNode without also deleting the SaveFrameNode it is inside of is meaningless.
SaveFrameNode OK Deleting a SaveFrameNode will delete all its contents.
SaveHeadingNode Do Not Delete. Deleting a SaveHeadingNode without also deleting the SaveFrameNode it is inside of is meaningless.
StarListNode Do Not Delete. Deleting a StarListNode without also deleting the StarFileNode it is inside of is meaningless.
StarFileNode OK Deleting the StarFileNode will delete the entire star file tree from memory.


Examples:

Here's an example code snippet to delete a saveframe called "save_delete_me":
	//Assume "AST" is a ptr to a StarFileNode:
	List<ASTnode*> *matches = AST->searchByTag( "save_delete_me" );
	
	//In reality, we know that there should be one match, so this
	//for-loop is probably overkill:
	for( matches->Reset() ; ! matches->AtEnd() ; matches->Next() )
	    if( matches->Current()->isOfType( ASTnode::SAVEFRAME )
		delete matches->Current();
        
	// You must always delete the list returned by the search
	// function when you are done with it 
	delete results;
    
Here is an example to delete all DataItemNodes that have a tag name "_Author_first_name" with a value of "Zaphod":
	//Assume "AST" is a ptr to a StarFileNode:
	List<ASTnode*> *matches =
	    AST->searchForTypeByTagValue(
	       ASTnode::DATAITEMNODE, "_Author_first_name", "Zaphod" );

	for( matches->Reset() ; ! matches->AtEnd() ; matches->Next() )
	    delete matches->Current();
        
	// You must always delete the list returned by the search
	// function when you are done with it 
	delete results;
    
Here is an example to delete from within a loop the column with the name "_looptag2". Note that because you are not supposed to directly delete the DataNameNodes that are inside a loop (according to the chart above), you must use a different technique here, namely calling the RemoveColumn method of DataLoopNode:
	//Assume "AST" is a ptr to a StarFileNode:
	List<ASTnode*> *matches = AST->searchForTag( "_looptag2" );

	for( matches->Reset() ; ! matches->AtEnd() ; matches->Next() )
	{
	    ASTnode *cur = matches->Current();
	    
	    // Walk up the parent list until the loop that this match
	    // was found inside of is reached.  If this match was not
	    // inside a loop, then this will walk all the way up to
	    // the root and eventually reach NULL.
	    while(  cur != NULL  &&
	            ! cur->isOfType( ASTnode::DATALOOPNODE )  )
	    {   cur = cur->myParent();
	    }
	    
	    // If we reached NULL, then the match was not in a loop,
	    // so only do something if it did not reach NULL: 
	    if( cur != NULL )
	    {   ((DataLoopNode*)cur)->RemoveColumn( "_looptag2" );
	    }
	}
        
	// You must always delete the list returned by the search
	// function when you are done with it 
	delete results;
    

- previous topic - - next topic -