Starlib: example 1

(Finding something)

This example shows how to find a particular tag you are looking for. Let's say that you want to retrieve the data associated with the tag called "_Author_name".

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 search for a tag, use the method searchByTag(). This is a member function of ASTnode, so you can be assured that it exists at all levels of the star file tree.

	List<ASTnode*> *results;
	results = AST->searchByTag( "_Author_name" );

	Write some code here to look at the results list
	to see what's in it, and do whatever you wanted to do with
	the matches that were found.
        
	// You must always delete the list returned by the search
	// function when you are done with it 
	delete results;
    
At this point, results is a list of all the hits that were returned by searchByTag. All the searching functions are designed to return a List of hits rather than one single hit, since they could be used in places where there are multiple matched items. For example, in this code it is perfectly possible to find multiple tags with the name "_Author_name" in different save frames, since we are searching the contents of the entire star file.

Now that we have a list of all the matches to "_Author_name", we can walk through them all and do whatever it was that was intended by this code. (Note, see list.h for a list of all the primitives that can be performed on the List template class):

	List<ASTnode*> *results;
	results = AST->searchByTag( "_Author_name" );

	for( results->Reset() ; ! results->AtEnd() ; results->Next() )
	{
	    ASTnode *thisOne = results->Current();
	    ...
	    Now do whatever you wanted to do with thisOne
	    ...
	}
        
	// You must always delete the list returned by the search
	// function when you are done with it 
	delete results;
    

But we have a problem here, and that is that all we have in the list of matches are pointers to the generic type ASTnode. What if we were expecting to get a DataItemNode and we wanted to only act on those hits that were DataItemNodes? (In other words, we don't want to operate on any matches we found inside a loop.)

This is where the self-awareness of the starlib classes comes in. All the classes in starlib are aware of what their own types are. (See the functions in astnode.h for explanations of the functions used here.) Therefore it is possible to query the matched nodes and ask them what they are. Also, each node is aware of what STAR file element it is inside of. (In other words, what its parent is in the star file tree). These two things combined can be used to determine what kind of thing the match was found inside of. Going back to the example above, we might add these lines:

	List<ASTnode*> *results;
	results = AST->searchByTag( "_Author_name" );

	for( results->Reset() ; ! results->AtEnd() ; results->Next() )
	{
	    ASTnode *thisOne = results->Current();
	    
	    // Walk up the parent tree until something that is a
	    // DATAITEMNODE is found, or the root of the tree is
	    // passed up:
	    while(   thisOne != NULL  &&
	             ! thisOne->isOfType( ASTnode::DATAITEMNODE )   )
	    {
		thisOne = thisOne->myParent();
	    }
	    if( thisOne != NULL )
	    {
	        Now do whatever you wanted to do with thisOne
	    }
	}
        
	// You must always delete the list returned by the search
	// function when you are done with it 
	delete results;
    
The methods shown above, isOfType() and myParent(), as well as the possible types for ASTtype (the argument to isOfType()) are described in astnode.h

NOTE: Despite its name, searchByTag() can be used to search for any sort of name, not just tags. For example, you could search for a save frame.

Other similar searching functions that might be of interest are:

These are all described in detail in astnode.h.
- previous topic - - next topic -