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. |
//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;