00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef NCL_NXSBLOCK_H
00020 #define NCL_NXSBLOCK_H
00021
00022 #include <vector>
00023 #include "ncl/nxsdefs.h"
00024 #include "ncl/nxsexception.h"
00025 #include "ncl/nxstoken.h"
00026
00027 class NxsReader;
00028 class NxsBlock;
00029 class NxsTaxaBlockAPI;
00030
00031 typedef std::vector<NxsBlock *> VecBlockPtr;
00032 typedef std::vector<const NxsBlock *> VecConstBlockPtr;
00033 typedef std::pair<const NxsBlock *, std::string> BlockUniqueID;
00034 typedef std::map<BlockUniqueID, NxsBlock *> NxsBlockMapper;
00035
00036
00037
00044 class NxsLabelToIndicesMapper
00045 {
00046 public:
00047 virtual ~NxsLabelToIndicesMapper(){}
00048 virtual unsigned GetMaxIndex() const = 0;
00049
00050
00051
00052
00053
00054 virtual unsigned GetIndicesForLabel(const std::string &label,
00055 NxsUnsignedSet *inds
00056 ) const = 0;
00057
00058
00059
00060
00061
00062 virtual unsigned GetIndexSet(const std::string &label, NxsUnsignedSet * toFill) const = 0;
00063
00064
00065
00066 virtual bool AddNewIndexSet(const std::string &label, const NxsUnsignedSet & inds) = 0;
00067
00068
00069
00070 virtual bool AddNewPartition(const std::string &label, const NxsPartition & inds) = 0;
00071
00072
00073
00074
00075
00076 virtual unsigned AppendNewLabel(std::string &)
00077 {
00078 throw NxsUnimplementedException("AppendNewLabel called on fixed label interface");
00079 }
00080 protected:
00081 static unsigned GetIndicesFromSets(const std::string &label, NxsUnsignedSet *inds, const NxsUnsignedSetMap & itemSets);
00082 static unsigned GetIndicesFromSetOrAsNumber(const std::string &label, NxsUnsignedSet *inds, const NxsUnsignedSetMap & itemSets, const unsigned maxInd, const char * itemType);
00083 };
00084
00085 class NxsSetVectorItemValidator;
00086
00087 std::string GetBlockIDTitleString(NxsBlock &);
00097 class NxsBlock
00098 {
00099 friend class NxsReader;
00100
00101 public:
00102 enum NxsBlockLinkStatus
00103 {
00104 BLOCK_LINK_UNINITIALIZED = 0x00,
00105 BLOCK_LINK_UNKNOWN_STATUS = 0x01,
00106 BLOCK_LINK_TO_ONLY_CHOICE = 0x02,
00107 BLOCK_LINK_TO_MOST_RECENT = 0x04,
00108 BLOCK_LINK_TO_IMPLIED_BLOCK = 0x08,
00109 BLOCK_LINK_FROM_LINK_CMD = 0x10,
00110 BLOCK_LINK_EQUIVALENT_TO_IMPLIED = 0x20,
00111 BLOCK_LINK_UNUSED_MASK = 0x3F,
00112 BLOCK_LINK_USED = 0x40
00113 };
00114 enum NxsCommandResult
00115 {
00116 STOP_PARSING_BLOCK,
00117 HANDLED_COMMAND,
00118 UNKNOWN_COMMAND
00119 };
00120 NxsBlock();
00121 virtual ~NxsBlock();
00122
00123 virtual void SetNexus(NxsReader *nxsptr);
00124 NxsReader *GetNexus() const;
00125 virtual bool CanReadBlockType(const NxsToken & token)
00126 {
00127 return token.Equals(id);
00128 }
00129
00130 NxsString GetID() const;
00131 bool IsEmpty() NCL_COULD_BE_CONST ;
00132
00133 void Enable();
00134 void Disable();
00135 bool IsEnabled() NCL_COULD_BE_CONST ;
00136 bool IsUserSupplied() NCL_COULD_BE_CONST ;
00137
00138 virtual unsigned CharLabelToNumber(NxsString s) NCL_COULD_BE_CONST ;
00139 virtual unsigned TaxonLabelToNumber(NxsString s) const;
00140
00141 virtual void SkippingCommand(NxsString commandName);
00142
00143 virtual void HandleBlockIDCommand(NxsToken &token);
00144 virtual void HandleEndblock(NxsToken &token);
00145 virtual void HandleLinkCommand(NxsToken &token);
00146 virtual void HandleTitleCommand(NxsToken &token);
00147
00148 virtual void Report(std::ostream &out) NCL_COULD_BE_CONST ;
00149 virtual void Reset();
00150
00151 mutable NxsString errormsg;
00152
00153
00154 virtual VecBlockPtr GetImpliedBlocks();
00155 virtual VecConstBlockPtr GetImpliedBlocksConst() const;
00156 BlockUniqueID GetInstanceIdentifier() const
00157 {
00158 return BlockUniqueID(this, GetInstanceName());
00159 }
00160
00161 const std::string &GetInstanceName() const
00162 {
00163 return title;
00164 }
00165 virtual NxsBlock *CloneBlock(NxsBlockMapper &memo) const;
00166 bool ImplementsLinkAPI() const;
00167 void SetImplementsLinkAPI(bool v);
00168
00169 virtual void WriteAsNexus(std::ostream &out) const;
00170 virtual void WriteBlockIDCommand(std::ostream &out) const;
00171 virtual void WriteLinkCommand(std::ostream &out) const;
00172 virtual void WriteTitleCommand(std::ostream &out) const;
00173 std::string GetTitle() const
00174 {
00175 return title;
00176 }
00177 void SetTitle(const std::string &t, bool autogeneratedTitle)
00178 {
00179 title = t;
00180
00181 autoTitle = autogeneratedTitle;
00182 }
00183 bool IsAutoGeneratedTitle() const
00184 {
00185 return autoTitle;
00186 }
00187 void StoreSkippedCommands(bool v)
00188 {
00189 storeSkippedCommands = v;
00190 }
00191 void ClearStoredSkippedCommands()
00192 {
00193 skippedCommands.clear();
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 virtual void CopyBaseBlockContents(const NxsBlock &other)
00206 {
00207 errormsg = other.errormsg;
00208 isEmpty = other.isEmpty;
00209 isEnabled = other.isEnabled;
00210 isUserSupplied = other.isUserSupplied;
00211 id = other.id;
00212 title = other.title;
00213
00214 blockIDString = other.blockIDString;
00215 linkAPI = other.linkAPI;
00216 storeSkippedCommands = other.storeSkippedCommands;
00217 skippedCommands = other.skippedCommands;
00218 autoTitle = other.autoTitle;
00219 }
00220
00221 virtual NxsBlock * Clone() const
00222 {
00223 NxsBlock * b = new NxsBlock();
00224 b->CopyBaseBlockContents(*this);
00225 b->nexusReader = NULL;
00226 b->next = NULL;
00227 return b;
00228 }
00229
00230 unsigned ReadVectorPartitionDef(NxsPartition &np, NxsLabelToIndicesMapper <m, const std::string & partName, const char * ptype, const char * cmd, NxsToken & token, bool warnAsterisked, bool demandAllInds, NxsSetVectorItemValidator & v);
00231 void ReadPartitionDef(NxsPartition &np, NxsLabelToIndicesMapper <m, const std::string & partName, const char * ptype, const char * cmd, NxsToken & token, bool warnAsterisked, bool demandAllInds, bool storeAsPartition);
00232 virtual bool TolerateEOFInBlock() const
00233 {
00234 return false;
00235 }
00236 void WarnDangerousContent(const std::string &s, const NxsToken &t);
00237 void WarnDangerousContent(const std::string &s, const ProcessedNxsToken &t);
00238
00239 void WriteBasicBlockCommands(std::ostream & out) const;
00240 virtual void WriteSkippedCommands(std::ostream & out) const;
00241
00242 virtual bool SwapEquivalentTaxaBlock(NxsTaxaBlockAPI * )
00243 {
00244 return false;
00245 }
00251 std::string GetBlockIDCommandString() const { return blockIDString; }
00252 protected:
00253 void SkipCommand(NxsToken & token);
00254
00255 NxsCommandResult HandleBasicBlockCommands(NxsToken & token);
00256 void DemandEndSemicolon(NxsToken &token, const char *contextString) const;
00257 void DemandEquals(NxsToken &token, const char *contextString) const;
00258 void DemandEquals(ProcessedNxsCommand::const_iterator &tokIt, const ProcessedNxsCommand::const_iterator & endIt, const char *contextString) const ;
00259 void DemandIsAtEquals(NxsToken &token, const char *contextString) const;
00260 unsigned DemandPositiveInt(NxsToken &token, const char *contextString) const;
00261 void GenerateNxsException(NxsToken &token, const char *message = NULL) const;
00262 void GenerateUnexpectedTokenNxsException(NxsToken &token, const char *expected = NULL) const;
00263 bool isEmpty;
00264 bool isEnabled;
00265 bool isUserSupplied;
00266 NxsReader *nexusReader;
00267 NxsBlock *next;
00268 NxsString id;
00269 std::string title;
00270 std::string blockIDString;
00271 bool linkAPI;
00272 bool autoTitle;
00273 bool storeSkippedCommands;
00274 std::list<ProcessedNxsCommand> skippedCommands;
00275
00276 virtual void Read(NxsToken &token);
00277
00278 private:
00279 NxsBlock &operator=(const NxsBlock &other);
00280
00281 };
00282
00299 class NxsBlockFactory
00300 {
00301 public:
00302 virtual ~NxsBlockFactory()
00303 {
00304 }
00307 virtual NxsBlock * GetBlockReaderForID(const std::string & id,
00308 NxsReader *reader,
00309 NxsToken *token
00310 ) = 0;
00311
00317 virtual void BlockError(NxsBlock *b)
00318 {
00319 delete b;
00320 }
00327 virtual void BlockSkipped(NxsBlock *b)
00328 {
00329 delete b;
00330 }
00331 };
00332
00336 inline void NxsBlock::SetNexus(
00337 NxsReader *nxsptr)
00338 {
00339 nexusReader = nxsptr;
00340 }
00344 inline NxsReader * NxsBlock::GetNexus() const
00345 {
00346 return nexusReader;
00347 }
00348
00349
00357 inline void NxsBlock::DemandEquals(NxsToken &token, const char *contextString) const
00358 {
00359 token.GetNextToken();
00360 DemandIsAtEquals(token, contextString);
00361 }
00362 #endif
00363
00364