NxsReader Class Reference

This is the class that orchestrates the reading of a NEXUS data file, and so is the central class to NCL. More...

#include <nxsreader.h>

List of all members.

Public Types

enum  NxsWarnLevel {

Public Member Functions

 NxsReader ()
virtual void Add (NxsBlock *newBlock)
void Detach (NxsBlock *newBlock)
virtual void AddFactory (NxsBlockFactory *)
void RemoveFactory (NxsBlockFactory *)
virtual void Execute (NxsToken &token, bool notifyStartStop=true)
void ReadFilepath (const char *filename)
void ReadFilestream (std::istream &inf)
void ReadStringAsNexusContent (const std::string &s)
virtual void DebugReportBlock (NxsBlock &nexusBlock)
const char * NCLNameAndVersion ()
const char * NCLCopyrightNotice ()
const char * NCLHomePageURL ()
virtual void ExecuteStarting ()
virtual void ExecuteStopping ()
virtual bool EnteringBlock (NxsString blockName)
virtual void ExitingBlock (NxsString blockName)
virtual void OutputComment (const NxsString &comment)
virtual void SkippingDisabledBlock (NxsString blockName)
virtual void SkippingBlock (NxsString blockName)
virtual void NexusWarn (const std::string &s, NxsWarnLevel warnLevel, file_pos pos, long line, long col)
void NexusWarnToken (const std::string &m, NxsWarnLevel warnLevel, const ProcessedNxsToken &token)
void NexusWarnToken (const std::string &m, NxsWarnLevel warnLevel, const NxsToken &token)
virtual void NexusError (NxsString msg, file_pos pos, long line, long col)
virtual void ClearUsedBlockList ()
NxsBlockCreateBlockFromFactories (const std::string &currBlockName, NxsToken &token, NxsBlockFactory **sourceOfBlock=NULL)
BlockReaderList GetUsedBlocksInOrder ()
BlockReaderList GetBlocksFromLastExecuteInOrder ()
BlockTypeToBlockList GetUsedBlocks ()
std::set< NxsBlock * > GetSetOfAllUsedBlocks ()
NxsTaxaBlockAPIGetLastStoredTaxaBlock ()
NxsCharactersBlockAPIGetLastStoredCharactersBlock ()
NxsTreesBlockAPI * GetLastStoredTreesBlock ()
NxsTaxaBlockAPIGetTaxaBlockByTitle (const char *title, unsigned *nMatches)
NxsCharactersBlockAPIGetCharBlockByTitle (const char *title, unsigned *nMatches)
NxsTreesBlockAPI * GetTreesBlockByTitle (const char *title, unsigned *nMatches)
NxsTaxaBlockFactory * GetTaxaBlockFactory ()
void SetTaxaBlockFactory (NxsTaxaBlockFactory *)
virtual void DeleteBlocksFromFactories ()
unsigned RemoveBlockFromUsedBlockList (NxsBlock *)
virtual void ClearContent ()
virtual void AddReadBlock (const NxsString &blockID, NxsBlock *block)
void cullIdenticalTaxaBlocks (bool v=true)
std::vector< std::string > GetAllTitlesForBlock (const NxsBlock *b) const
void SetAlwaysReportStatusMessages (bool v)
void SetWarningOutputLevel (NxsWarnLevel lev)
virtual void statusMessage (const std::string &m) const
bool BlockListEmpty ()
unsigned PositionInBlockList (NxsBlock *b)
void Reassign (NxsBlock *oldb, NxsBlock *newb)
void AssignBlockPriority (NxsBlock *b, int priorityLevel)
int GetBlockPriority (NxsBlock *b) const
void DemoteBlocks (int priorityLevel=-1)

Static Public Member Functions

static void setNCLCatchesSignals (bool)
static bool getNCLCatchesSignals ()
static unsigned getNumSignalIntsCaught ()
static void setNumSignalsIntsCaught (unsigned)

Protected Member Functions

void CoreExecutionTasks (NxsToken &token, bool notifyStartStop=true)
void AddBlockToUsedBlockList (const std::string &, NxsBlock *, NxsToken *)
bool BlockIsASingeltonReader (NxsBlock *) const
void BlockReadHook (const NxsString &currBlockName, NxsBlock *currBlock, NxsToken *token=NULL)
bool ExecuteBlock (NxsToken &token, const NxsString &currBlockName, NxsBlock *currBlock, NxsBlockFactory *sourceOfBlock)
NxsBlockFindBlockOfTypeByTitle (const std::string &btype, const char *title, unsigned *nMatches)
NxsBlockFindBlockByTitle (const BlockReaderList &chosenBlockList, const char *title, unsigned *nMatches)
NxsBlockGetLastStoredBlockByID (const std::string &key)
NxsTaxaBlockAPIGetOriginalTaxaBlock (const NxsTaxaBlockAPI *) const
bool IsRepeatedTaxaBlock (const NxsTaxaBlockAPI *) const
void NewBlockTitleCheckHook (const std::string &blockname, NxsBlock *p, NxsToken *token)
bool ReadUntilEndblock (NxsToken &token, const std::string &currBlockName)
void RegisterAltTitle (const NxsBlock *b, std::string t)
std::set< NxsBlock * > RemoveBlocksFromFactoriesFromUsedBlockLists ()
virtual void PostBlockReadingHook (NxsBlock &)

Static Protected Member Functions

static BlockReaderList parseFileWithReader (NxsReader &reader, const char *filepath, bool parsePrivateBlocks=true, bool storeTokenInfo=true)

Detailed Description

This is the class that orchestrates the reading of a NEXUS data file, and so is the central class to NCL.

NxsReader does not call delete on any of the blocks that are added to it via the Add method.

In the "classic" (v2.0) NCL API:

  1. An NxsReader is created.
  2. pointers to instances of NxsBlocks that are expected to be needed should be added to `blockList' using the NxsReader::Add() member function.
  3. NxsReader::Execute() is then called, which reads the data file until encountering a block name, at which point the correct block is looked up in `blockList' and that object's NxsBlock::Read() method is called.
  4. NxsReader::PostBlockReadingHook(NxsBlock) is called after a block is successfully read. This allows one to gather the parsed data from the NxsBlock. If another block of the same type is encountered, then NxsBlock::Reset() will be called and the same NxsBlock instance will be used to read the next block.

Versions of NCL after 2.0.04 also support a "factory API" augments the former behavior:

  1. An NxsReader is created.
  2. In addition to NxsBlocks added using the Add method, you can register instances of a NxsBlockFactory using the NxsReader::AddFactory() method.
  3. In the NxsReader::Execute() method, if an appropriate block is not found in the `blockList` then the the factories are asked to create a block for the current block name. The first non-NULL block pointer returned is used.
  4. PostBlockReadingHook is still called, but blocks created by a factory will not be "recycled" later in the NxsReader::Execute(), so it is not necessary to pull all of the data out of them. -If a block created by a factory is skipped or has an error, then the factory will be notified using NxsBlockFactory::BlockError(NxsBlock *) or NxsBlockFactory::BlockSkipped(NxsBlock *). In the event of skipping or an error, NxsReader will never refer to that instance of the factory-created block again. Hence the base class behavior of BlockError() and BlockSkipped() is to delete the instance.
  5. Every time a NxsBlock successfully reads a NEXUS block, the NxsBlock is added to container of "used" blocks. When a block is Reset() it is removed from this container. NxsReader::GetUsedBlocks() can be called at any point to get a copy of this container (which maps a block type name to a list of NxsBlock*). This container thus stores the state of the parsed NEXUS file. If no blocks were recycled (if all of the blocks came from factories rather than blocks added using NxsReader::Add() method), then the GetUsedBlocks will contain binary representation of every block parsed.

Important: The use of the factories that are supplied with NCL can trigger casts of pointers. This can be unsafe if you create NxsBlocks that do not have the expected inheritance. For example, if you create a class to read Taxa blocks, but do NOT derive this class from NxsTaxaBlockAPI then the casts will be unsafe. If you do this, and you wish to use the factory API then you must write your own factories.

See NCL_TOP/examples/normalizer examples for an example of the factory API (using the MultiFormatReader). In those examples the PublicNexusReader::PublicNexusReader() constructor is the function that installs the templates for a clone factory.

Errors in NEXUS files

When an illegal construct is found, a NxsException is raised. This exception is caught within NxsReader::Execute and NxsReader::NexusError is called. This allows subclasses of NxsReader to handle exceptional circumstances by overriding one function. Whenever you are using a NxsReader instance that is NOT a subclass of ExceptionRaisingNxsReader this is still the behavior (thus any code that was written to the v2.0 API will still have this behavior).

ExceptionRaisingNxsReader implements NexusError by raising another NxsException. This results in the exception being propagated to the caller. The newer NxsReader classes (including PublicNexusReader and MultiFormatReader) are derived from ExceptionRaisingNxsReader. So their Execute methods will also raise NxsExceptions. Deriving a subclass of these classes and overriding NexusError would prevent this behavior.

The advantage of ExceptionRaisingNxsReader is that one is no longer required to subclass NxsReader to handle errors.

Signal Handling in NCL:

Traditionally, the user of an application can send an SIGINT to cause it to stop. NCL has very limited support for handling signals, and this support is turned off by default.

If you want NCL to raise an NxsSignalCanceledParseException if a signal is encountered during a parse then call: NxsReader::setNCLCatchesSignals(true); before calling Execute on your NxsReader instance. Note that only the slowly-parsed blocks (TREES and CHARACTERS) and the NxsReader currently check to see if a signal has been caught. So the NxsSignalCanceledParseException will often have a generic message indicating that the signal was caught during the parse.

The NCL signal handler is only installed during NxsReader::Execute calls!

Note: that if you want your program to exit on SIGINT, you can leave the signal handling turned off. If you do turn NCL's signal handling on, then after you do your apps clean up you'll have to exit by something like this: signal(SIGINT, SIG_DFL); kill(getpid(), SIGINT);

See also:

Definition at line 118 of file nxsreader.h.

The documentation for this class was generated from the following files:
 All Classes Functions Variables Enumerations Enumerator Friends
Generated on Mon Mar 29 16:37:13 2010 for NCL by  doxygen 1.6.3