00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <istream>
00023 #include <fstream>
00024 #include "ncl/nxspublicblocks.h"
00025 #include "ncl/nxsreader.h"
00026 using namespace std;
00027
00028
00036 NxsTaxaBlock * PublicNexusReader::RegisterTaxa(const std::vector<std::string> & tl) {
00037 if (tl.empty()) {
00038 return 0L;
00039 }
00040 NxsTaxaBlock *tb = new NxsTaxaBlock();
00041 tb->SetNtax(tl.size());
00042 for (std::vector<std::string>::const_iterator labelIt = tl.begin(); labelIt != tl.end(); ++labelIt)
00043 tb->AddTaxonLabel(*labelIt);
00044 AddReadTaxaBlock(tb);
00045 return tb;
00046 }
00047
00049 BlockReaderList PublicNexusReader::parseFileOrThrow(
00050 const char *filepath,
00051 NxsReader::WarningHandlingMode mode,
00052 bool parsePrivateBlocks,
00053 bool storeTokenInfo)
00054 {
00055 PublicNexusReader nexusReader(mode);
00056 return NxsReader::parseFileWithReader(nexusReader, filepath, parsePrivateBlocks, storeTokenInfo);
00057 }
00058
00059 BlockReaderList DefaultErrorReportNxsReader::parseFile(
00060 const char *filepath,
00061 std::ostream * stdOutstream,
00062 std::ostream * errOutstream,
00063 bool parsePrivateBlocks,
00064 bool storeTokenInfo)
00065 {
00066 DefaultErrorReportNxsReader nexusReader(stdOutstream, errOutstream);
00067 return NxsReader::parseFileWithReader(nexusReader, filepath, parsePrivateBlocks, storeTokenInfo);
00068 }
00069
00075 BlockReaderList NxsReader::parseFileWithReader(
00076 NxsReader & nexusReader,
00077 const char *filepath,
00078 bool parsePrivateBlocks,
00079 bool storeTokenInfo)
00080 {
00081 if (!filepath)
00082 nexusReader.NexusError("Invalid (NULL) file specified to be parsed", 0, -1, -1);
00083 ifstream inf(filepath, ios::binary);
00084 if (!inf.good())
00085 {
00086 NxsString err;
00087 err << "Could not parse the file \"" << filepath <<"\"";
00088 nexusReader.NexusError(err, 0, -1, -1);
00089 }
00090 nexusReader.statusMessage("Creating token");
00091 NxsToken token(inf);
00092 NxsDefaultPublicBlockFactory factory(parsePrivateBlocks, storeTokenInfo);
00093 nexusReader.AddFactory(&factory);
00094 try {
00095 nexusReader.statusMessage("Executing");
00096 nexusReader.Execute(token);
00097 }
00098 catch(...)
00099 {
00100 nexusReader.RemoveFactory(&factory);
00101 throw;
00102 }
00103 nexusReader.RemoveFactory(&factory);
00104 BlockReaderList brl = nexusReader.GetBlocksFromLastExecuteInOrder();
00105 return brl;
00106 }
00107
00108
00109 void NxsStoreTokensBlockReader::Reset()
00110 {
00111 NxsBlock::Reset();
00112 commandsRead.clear();
00113 }
00114
00115 void NxsStoreTokensBlockReader::ReportConst(std::ostream &out) const
00116 {
00117 out << id << " block contains ";
00118 if (storeAllTokenInfo)
00119 {
00120 out << (unsigned)commandsRead.size() << " commands:\n";
00121 for (std::list<ProcessedNxsCommand>::const_iterator cIt = commandsRead.begin(); cIt != commandsRead.end(); ++cIt)
00122 {
00123 const ProcessedNxsToken & t = (*cIt)[0];
00124 out << " " << t.GetToken() << "\n";
00125 }
00126 }
00127 else
00128 {
00129 out << (unsigned)justTokens.size() << " commands:\n";
00130 for (ListVecString::const_iterator cIt = justTokens.begin(); cIt != justTokens.end(); ++cIt)
00131 out << " " << cIt->at(0) << "\n";
00132 }
00133 }
00134
00135 void NxsStoreTokensBlockReader::ReadCommand(
00136 NxsToken &token)
00137 {
00138 if (storeAllTokenInfo)
00139 {
00140 ProcessedNxsCommand fullTokens;
00141 token.ProcessAsCommand(&fullTokens);
00142 if (!fullTokens.empty())
00143 commandsRead.push_back(fullTokens);
00144 }
00145 else
00146 {
00147 VecString justString;
00148 while (!token.Equals(";"))
00149 {
00150 justString.push_back(token.GetToken());
00151 token.GetNextToken();
00152 }
00153 if (!justString.empty())
00154 justTokens.push_back(justString);
00155 }
00156 }
00157
00158 void NxsStoreTokensBlockReader::Read(
00159 NxsToken &token)
00160 {
00161 isEmpty = false;
00162 isUserSupplied = true;
00163 NxsString begcmd("BEGIN ");
00164 begcmd += this->id;
00165 DemandEndSemicolon(token, begcmd.c_str());
00166
00167 for(;;)
00168 {
00169 token.GetNextToken();
00170 if (token.Equals("END") || token.Equals("ENDBLOCK"))
00171 {
00172 HandleEndblock(token);
00173 return ;
00174 }
00175 this->ReadCommand(token);
00176 }
00177 }
00178
00179 void NxsStoreTokensBlockReader::WriteAsNexus(std::ostream &out) const
00180 {
00181 out << "BEGIN " << NxsString::GetEscaped(this->id) << ";\n";
00182 if (storeAllTokenInfo)
00183 {
00184 for (std::list<ProcessedNxsCommand>::const_iterator cIt = commandsRead.begin(); cIt != commandsRead.end(); ++cIt)
00185 {
00186 const ProcessedNxsCommand & t = *cIt;
00187 if (WriteCommandAsNexus(out, t))
00188 out << '\n';
00189 }
00190 }
00191 else
00192 {
00193 for (ListVecString::const_iterator cIt = justTokens.begin(); cIt != justTokens.end(); ++cIt)
00194 {
00195 const VecString & t = *cIt;
00196 out << " ";
00197 for (VecString::const_iterator wIt = t.begin(); wIt != t.end(); ++wIt)
00198 out << ' ' << NxsString::GetEscaped(*wIt);
00199 out << ";\n";
00200 }
00201 }
00202 WriteSkippedCommands(out);
00203 out << "END;\n";
00204 }
00205
00208 NxsBlock *NxsDefaultPublicBlockFactory::GetBlockReaderForID(
00209 const std::string & id,
00210 NxsReader *reader,
00211 NxsToken *token)
00212 {
00213 if (id == "ASSUMPTIONS" || id == "SETS")
00214 return assumpBlockFact.GetBlockReaderForID(id, reader, token);
00215 if (id == "CHARACTERS")
00216 return charBlockFact.GetBlockReaderForID(id, reader, token);
00217 if (id == "DATA")
00218 return dataBlockFact.GetBlockReaderForID(id, reader, token);
00219 if (id == "DISTANCES")
00220 return distancesBlockFact.GetBlockReaderForID(id, reader, token);
00221 if (id == "TAXA")
00222 return taxaBlockFact.GetBlockReaderForID(id, reader, token);
00223 if (id == "TREES")
00224 return treesBlockFact.GetBlockReaderForID(id, reader, token);
00225 if (id == "UNALIGNED")
00226 return unalignedBlockFact.GetBlockReaderForID(id, reader, token);
00227 if (tokenizeUnknownBlocks)
00228 {
00229 NxsStoreTokensBlockReader * nb = new NxsStoreTokensBlockReader(id, storeTokenInfoArg);
00230 nb->SetImplementsLinkAPI(false);
00231 return nb;
00232 }
00233 return NULL;
00234 }
00235
00246 PublicNexusReader::PublicNexusReader(
00247 const int blocksToRead,
00248 NxsReader::WarningHandlingMode warnModeArg)
00249 :ExceptionRaisingNxsReader(warnModeArg),
00250 bitsForBlocksToRead(blocksToRead),
00251 assumptionsBlockTemplate(0L),
00252 charactersBlockTemplate(0L),
00253 dataBlockTemplate(0L),
00254 distancesBlockTemplate(0L),
00255 storerBlockTemplate(0L),
00256 taxaBlockTemplate(0L),
00257 treesBlockTemplate(0L),
00258 unalignedBlockTemplate(0L)
00259 {
00260 this->AddFactory(&cloneFactory);
00261
00262 taxaBlockTemplate = new NxsTaxaBlock();
00263 taxaBlockTemplate->SetImplementsLinkAPI(false);
00264 cloneFactory.AddPrototype(taxaBlockTemplate);
00265
00266 if (blocksToRead & NEXUS_ASSUMPTIONS_BLOCK_BIT)
00267 {
00268 assumptionsBlockTemplate = new NxsAssumptionsBlock(0L);
00269 assumptionsBlockTemplate->SetImplementsLinkAPI(true);
00270 cloneFactory.AddPrototype(assumptionsBlockTemplate, "ASSUMPTIONS");
00271 cloneFactory.AddPrototype(assumptionsBlockTemplate, "SETS");
00272 cloneFactory.AddPrototype(assumptionsBlockTemplate, "CODONS");
00273 }
00274
00275 if (blocksToRead & NEXUS_TREES_BLOCK_BIT)
00276 {
00277 treesBlockTemplate = new NxsTreesBlock(NULL);
00278 treesBlockTemplate->SetCreateImpliedBlock(true);
00279 treesBlockTemplate->SetImplementsLinkAPI(true);
00280 treesBlockTemplate->SetProcessAllTreesDuringParse(true);
00281 treesBlockTemplate->SetAllowImplicitNames(true);
00282 treesBlockTemplate->SetWriteFromNodeEdgeDataStructure(true);
00283 cloneFactory.AddPrototype(treesBlockTemplate);
00284 }
00285 if (blocksToRead & NEXUS_CHARACTERS_BLOCK_BIT)
00286 {
00287 charactersBlockTemplate = new NxsCharactersBlock(NULL, NULL);
00288 charactersBlockTemplate->SetCreateImpliedBlock(true);
00289 charactersBlockTemplate->SetImplementsLinkAPI(true);
00290 charactersBlockTemplate->SetSupportMixedDatatype(true);
00291 charactersBlockTemplate->SetConvertAugmentedToMixed(true);
00292
00293 dataBlockTemplate = new NxsDataBlock(NULL, NULL);
00294 dataBlockTemplate->SetCreateImpliedBlock(true);
00295 dataBlockTemplate->SetImplementsLinkAPI(true);
00296 dataBlockTemplate->SetSupportMixedDatatype(true);
00297 dataBlockTemplate->SetConvertAugmentedToMixed(true);
00298 cloneFactory.AddPrototype(charactersBlockTemplate, "CHARACTERS");
00299 cloneFactory.AddPrototype(dataBlockTemplate, "DATA");
00300 }
00301 if (blocksToRead & NEXUS_UNALIGNED_BLOCK_BIT)
00302 {
00303 unalignedBlockTemplate = new NxsUnalignedBlock(NULL);
00304 unalignedBlockTemplate->SetCreateImpliedBlock(true);
00305 unalignedBlockTemplate->SetImplementsLinkAPI(true);
00306 cloneFactory.AddPrototype(unalignedBlockTemplate);
00307 }
00308 if (blocksToRead & NEXUS_DISTANCES_BLOCK_BIT)
00309 {
00310 distancesBlockTemplate = new NxsDistancesBlock(NULL);
00311 distancesBlockTemplate->SetCreateImpliedBlock(true);
00312 distancesBlockTemplate->SetImplementsLinkAPI(true);
00313 cloneFactory.AddPrototype(distancesBlockTemplate);
00314 }
00315 if (blocksToRead & NEXUS_UNKNOWN_BLOCK_BIT)
00316 {
00317 std::string emptyString;
00318 storerBlockTemplate = new NxsStoreTokensBlockReader(emptyString, true);
00319 storerBlockTemplate->SetImplementsLinkAPI(false);
00320 cloneFactory.AddDefaultPrototype(storerBlockTemplate);
00321 }
00322 }
00323
00327 void PublicNexusReader::Execute(NxsToken& token, bool notifyStartStop)
00328 {
00329 NxsReader::Execute(token, notifyStartStop);
00330 PostExecuteHook();
00331 }
00332
00340 void PublicNexusReader::PostExecuteHook()
00341 {
00342 BlockReaderList blocks = GetBlocksFromLastExecuteInOrder();
00343 for (BlockReaderList::const_iterator bIt = blocks.begin(); bIt != blocks.end(); ++bIt)
00344 {
00345 NxsBlock * b = *bIt;
00346 const std::string id = b->GetID();
00347 const std::string capId = NxsString::get_upper(id);
00348 const char * capIdP = capId.c_str();
00349 if (strcmp(capIdP, "TAXA") == 0)
00350 taxaBlockVec.push_back(static_cast<NxsTaxaBlock *>(b));
00351 else if (strcmp(capIdP, "TREES") == 0)
00352 treesBlockVec.push_back(static_cast<NxsTreesBlock *>(b));
00353 else if ((strcmp(capIdP, "CHARACTERS") == 0) || (strcmp(capIdP, "DATA") == 0))
00354 charactersBlockVec.push_back(static_cast<NxsCharactersBlock *>(b));
00355 else if ((strcmp(capIdP, "ASSUMPTIONS") == 0) || (strcmp(capIdP, "SETS") == 0) || (strcmp(capIdP, "CODONS") == 0))
00356 assumptionsBlockVec.push_back(static_cast<NxsAssumptionsBlock *>(b));
00357 else if (strcmp(capIdP, "DISTANCES") == 0)
00358 distancesBlockVec.push_back(static_cast<NxsDistancesBlock *>(b));
00359 else if (strcmp(capIdP, "UNALIGNED") == 0)
00360 unalignedBlockVec.push_back(static_cast<NxsUnalignedBlock *>(b));
00361 else
00362 {
00363 storerBlockVec.push_back(static_cast<NxsStoreTokensBlockReader *>(b));
00364 }
00365 }
00366 }
00367
00368 void PublicNexusReader::AddFactory(NxsBlockFactory *f)
00369 {
00370 if (f == &cloneFactory)
00371 NxsReader::AddFactory(f);
00372 else
00373 {
00374 NCL_ASSERT(false);
00375 }
00376 }
00377
00378 PublicNexusReader::~PublicNexusReader()
00379 {
00380 delete assumptionsBlockTemplate;
00381 delete charactersBlockTemplate;
00382 delete dataBlockTemplate;
00383 delete distancesBlockTemplate;
00384 delete storerBlockTemplate;
00385 delete taxaBlockTemplate;
00386 delete treesBlockTemplate;
00387 delete unalignedBlockTemplate;
00388 }
00389
00390 unsigned PublicNexusReader::GetNumAssumptionsBlocks(const NxsTaxaBlock *taxa) const
00391 {
00392 unsigned n = 0;
00393 std::vector<NxsAssumptionsBlock *>::const_iterator bIt = assumptionsBlockVec.begin();
00394 for (; bIt != assumptionsBlockVec.end(); ++bIt)
00395 {
00396 NxsAssumptionsBlock * b = *bIt;
00397 if (taxa && taxa != b->taxa)
00398 continue;
00399 n++;
00400 }
00401 return n;
00402 }
00403
00404 NxsAssumptionsBlock * PublicNexusReader::GetAssumptionsBlock(const NxsTaxaBlock *taxa, unsigned index) const
00405 {
00406 unsigned n = 0;
00407 std::vector<NxsAssumptionsBlock *>::const_iterator bIt = assumptionsBlockVec.begin();
00408 for (; bIt != assumptionsBlockVec.end(); ++bIt)
00409 {
00410 NxsAssumptionsBlock * b = *bIt;
00411 if (taxa && taxa != b->taxa)
00412 continue;
00413 if (index == n)
00414 return b;
00415 n++;
00416 }
00417 return 0L;
00418 }
00419
00420 unsigned PublicNexusReader::GetNumAssumptionsBlocks( const NxsCharactersBlock * chars) const
00421 {
00422 unsigned n = 0;
00423 std::vector<NxsAssumptionsBlock *>::const_iterator bIt = assumptionsBlockVec.begin();
00424 for (; bIt != assumptionsBlockVec.end(); ++bIt)
00425 {
00426 NxsAssumptionsBlock * b = *bIt;
00427 if (chars && chars != b->charBlockPtr)
00428 continue;
00429 n++;
00430 }
00431 return n;
00432 }
00433
00434 NxsAssumptionsBlock * PublicNexusReader::GetAssumptionsBlock(const NxsCharactersBlock * chars, unsigned index) const
00435 {
00436 unsigned n = 0;
00437 std::vector<NxsAssumptionsBlock *>::const_iterator bIt = assumptionsBlockVec.begin();
00438 for (; bIt != assumptionsBlockVec.end(); ++bIt)
00439 {
00440 NxsAssumptionsBlock * b = *bIt;
00441 if (chars && chars != b->charBlockPtr)
00442 continue;
00443 if (index == n)
00444 return b;
00445 n++;
00446 }
00447 return 0L;
00448 }
00449
00450 unsigned PublicNexusReader::GetNumAssumptionsBlocks(const NxsTreesBlock *tree) const
00451 {
00452 unsigned n = 0;
00453 std::vector<NxsAssumptionsBlock *>::const_iterator bIt = assumptionsBlockVec.begin();
00454 for (; bIt != assumptionsBlockVec.end(); ++bIt)
00455 {
00456 NxsAssumptionsBlock * b = *bIt;
00457 if (tree && tree != b->treesBlockPtr)
00458 continue;
00459 n++;
00460 }
00461 return n;
00462 }
00463
00464 NxsAssumptionsBlock * PublicNexusReader::GetAssumptionsBlock(const NxsTreesBlock *tree, unsigned index) const
00465 {
00466 unsigned n = 0;
00467 std::vector<NxsAssumptionsBlock *>::const_iterator bIt = assumptionsBlockVec.begin();
00468 for (; bIt != assumptionsBlockVec.end(); ++bIt)
00469 {
00470 NxsAssumptionsBlock * b = *bIt;
00471 if (tree && tree != b->treesBlockPtr)
00472 continue;
00473 if (index == n)
00474 return b;
00475 n++;
00476 }
00477 return 0L;
00478 }
00479
00480 unsigned PublicNexusReader::GetNumCharactersBlocks(const NxsTaxaBlock *taxa) const
00481 {
00482 unsigned n = 0;
00483 std::vector<NxsCharactersBlock *>::const_iterator bIt = charactersBlockVec.begin();
00484 for (; bIt != charactersBlockVec.end(); ++bIt)
00485 {
00486 NxsCharactersBlock * b = *bIt;
00487 if (!taxa || taxa == b->taxa)
00488 n++;
00489 }
00490 return n;
00491 }
00492
00493 NxsCharactersBlock * PublicNexusReader::GetCharactersBlock(const NxsTaxaBlock *taxa, unsigned index) const
00494 {
00495 unsigned n = 0;
00496 std::vector<NxsCharactersBlock *>::const_iterator bIt = charactersBlockVec.begin();
00497 for (; bIt != charactersBlockVec.end(); ++bIt)
00498 {
00499 NxsCharactersBlock * b = *bIt;
00500 if (!taxa || taxa == b->taxa)
00501 {
00502 if (index == n)
00503 return b;
00504 n++;
00505 }
00506 }
00507 return 0L;
00508 }
00509
00510 unsigned PublicNexusReader::GetNumDistancesBlocks(const NxsTaxaBlock *taxa) const
00511 {
00512 unsigned n = 0;
00513 std::vector<NxsDistancesBlock *>::const_iterator bIt = distancesBlockVec.begin();
00514 for (; bIt != distancesBlockVec.end(); ++bIt)
00515 {
00516 NxsDistancesBlock * b = *bIt;
00517 if (!taxa || taxa == b->taxa)
00518 n++;
00519 }
00520 return n;
00521 }
00522
00523 NxsDistancesBlock * PublicNexusReader::GetDistancesBlock(const NxsTaxaBlock *taxa, unsigned index) const
00524 {
00525 unsigned n = 0;
00526 std::vector<NxsDistancesBlock *>::const_iterator bIt = distancesBlockVec.begin();
00527 for (; bIt != distancesBlockVec.end(); ++bIt)
00528 {
00529 NxsDistancesBlock * b = *bIt;
00530 if (!taxa || taxa == b->taxa)
00531 {
00532 if (index == n)
00533 return b;
00534 n++;
00535 }
00536 }
00537 return 0L;
00538 }
00539
00540 unsigned PublicNexusReader::GetNumUnalignedBlocks(const NxsTaxaBlock *taxa) const
00541 {
00542 unsigned n = 0;
00543 std::vector<NxsUnalignedBlock *>::const_iterator bIt = unalignedBlockVec.begin();
00544 for (; bIt != unalignedBlockVec.end(); ++bIt)
00545 {
00546 NxsUnalignedBlock * b = *bIt;
00547 if (!taxa || taxa == b->taxa)
00548 n++;
00549 }
00550 return n;
00551 }
00552
00553 NxsUnalignedBlock * PublicNexusReader::GetUnalignedBlock(const NxsTaxaBlock *taxa, unsigned index) const
00554 {
00555 unsigned n = 0;
00556 std::vector<NxsUnalignedBlock *>::const_iterator bIt = unalignedBlockVec.begin();
00557 for (; bIt != unalignedBlockVec.end(); ++bIt)
00558 {
00559 NxsUnalignedBlock * b = *bIt;
00560 if (!taxa || taxa == b->taxa)
00561 {
00562 if (index == n)
00563 return b;
00564 n++;
00565 }
00566 }
00567 return 0L;
00568 }
00569
00570
00571 unsigned PublicNexusReader::GetNumTreesBlocks(const NxsTaxaBlock *taxa) const
00572 {
00573 unsigned n = 0;
00574 std::vector<NxsTreesBlock *>::const_iterator bIt = treesBlockVec.begin();
00575 for (; bIt != treesBlockVec.end(); ++bIt)
00576 {
00577 NxsTreesBlock * b = *bIt;
00578 if (!taxa || taxa == b->taxa)
00579 n++;
00580 }
00581 return n;
00582 }
00583
00584 NxsTreesBlock * PublicNexusReader::GetTreesBlock(const NxsTaxaBlock *taxa, unsigned index) const
00585 {
00586 unsigned n = 0;
00587 std::vector<NxsTreesBlock *>::const_iterator bIt = treesBlockVec.begin();
00588 for (; bIt != treesBlockVec.end(); ++bIt)
00589 {
00590 NxsTreesBlock * b = *bIt;
00591 if (!taxa || taxa == b->taxa)
00592 {
00593 if (index == n)
00594 return b;
00595 n++;
00596 }
00597 }
00598 return 0L;
00599 }
00600
00601 unsigned PublicNexusReader::GetNumUnknownBlocks() const
00602 {
00603 return (unsigned)storerBlockVec.size();
00604 }
00605
00606 NxsStoreTokensBlockReader * PublicNexusReader::GetUnknownBlock(unsigned index) const
00607 {
00608 if (index < storerBlockVec.size())
00609 return storerBlockVec[index];
00610 return 0L;
00611 }
00612
00613 unsigned PublicNexusReader::GetNumTaxaBlocks() const
00614 {
00615 return (unsigned)taxaBlockVec.size();
00616 }
00617
00618 NxsTaxaBlock * PublicNexusReader::GetTaxaBlock(unsigned index) const
00619 {
00620 if (index < taxaBlockVec.size())
00621 return taxaBlockVec[index];
00622 return 0L;
00623 }
00624
00625 void PublicNexusReader::ClearUsedBlockList()
00626 {
00627 NxsReader::ClearUsedBlockList();
00628 assumptionsBlockVec.clear();
00629 charactersBlockVec.clear();
00630 dataBlockVec.clear();
00631 distancesBlockVec.clear();
00632 storerBlockVec.clear();
00633 taxaBlockVec.clear();
00634 treesBlockVec.clear();
00635 unalignedBlockVec.clear();
00636 }
00637
00638
00639
00640
00641 bool fileExists(const std::string &fn);
00642
00643
00644 bool fileExists(const std::string &fn)
00645 {
00646 std::ifstream inf;
00647 inf.open(fn.c_str());
00648 const bool b = inf.good();
00649 inf.close();
00650 return b;
00651 }
00652
00653 std::string NxsConversionOutputRecord::getUniqueFilenameWithLowestIndex(const char * prefix)
00654 {
00655 NxsString fn;
00656 fn.assign(prefix);
00657 const unsigned MAX_SUFFIX = 10000;
00658 for (unsigned i = 1; i <= MAX_SUFFIX ; ++i)
00659 {
00660 if (!fileExists(fn))
00661 return fn;
00662 fn.assign(prefix);
00663 fn << i;
00664 }
00665 fn.clear();
00666 fn << "Files \"" << prefix << "\" through \"" << prefix << MAX_SUFFIX << "\" exist, and I am afraid to write any more files to that directory. I quit.";
00667 throw NxsException(fn);
00668 }
00669
00670
00671
00672 void NxsConversionOutputRecord::writeTaxonNameTranslationFilepath(const char * fn, const std::vector<NxsNameToNameTrans> & nameTrans, const NxsTaxaBlockAPI *tb, bool verbose)
00673 {
00674 std::ofstream tnf;
00675 tnf.open(fn);
00676 if (!tnf.good())
00677 {
00678 NxsString msg;
00679 msg << "Could not open the file " << fn << " for writing translation of names";
00680 throw NxsException(msg);
00681 }
00682 if (verbose)
00683 std::cerr << "Writing \"" << fn << "\" to store the translation of names\n";
00684 writeTaxonNameTranslationStream(tnf, nameTrans, tb);
00685 tnf.close();
00686 }
00687
00688
00689
00690 void NxsConversionOutputRecord::writeTaxonNameTranslationStream(std::ostream & tnf, const std::vector<NxsNameToNameTrans> & nameTrans, const NxsTaxaBlockAPI *tb)
00691 {
00692 std::string blockLabel = tb->GetTitle();
00693 tnf << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
00694 tnf << "<taxa label=";
00695 writeAttributeValue(tnf, blockLabel);
00696 tnf << " >\n";
00697 for (std::vector<NxsNameToNameTrans>::const_iterator nIt = nameTrans.begin(); nIt != nameTrans.end(); ++nIt)
00698 {
00699 tnf << " <taxon src=";
00700 writeAttributeValue(tnf, nIt->first);
00701 tnf << " dest=";
00702 writeAttributeValue(tnf, nIt->second);
00703 tnf << " />\n";
00704 }
00705 tnf << "</taxa>\n";
00706 }
00707
00708 void NxsConversionOutputRecord::writeNameTranslation(std::vector<NxsNameToNameTrans> nameTrans, const NxsTaxaBlockAPI * taxa)
00709 {
00710 if (taxaBlocksToConversionFiles.find(taxa) != taxaBlocksToConversionFiles.end())
00711 return;
00712 std::string fn;
00713 if (this->numberTranslationFiles)
00714 fn = getUniqueFilenameWithLowestIndex(this->translationFilename.c_str());
00715 else
00716 fn = this->translationFilename;
00717 writeTaxonNameTranslationFilepath(fn.c_str(), nameTrans, taxa, this->verboseWritingOfNameTranslationFile);
00718 taxaBlocksToConversionFiles[taxa] = fn;
00719 }
00720
00721 void writeAttributeValue(ostream & out, const std::string & v)
00722 {
00723 if (v.c_str() == NULL)
00724 out << "\'\'";
00725 else
00726 {
00727
00728 if (v.find_first_of("\'\"&") != string::npos)
00729 {
00730 if (strchr(v.c_str(), '\'') != NULL)
00731 {
00732 out << '\"';
00733 for (std::string::const_iterator cIt = v.begin(); cIt != v.end(); ++cIt)
00734 {
00735 const char & c = *cIt;
00736 if (c == '\"')
00737 out << """;
00738 else if (c == '&')
00739 out << "&";
00740 else
00741 out << c;
00742 }
00743 out << '\"';
00744
00745 }
00746 else
00747 {
00748 out << '\'';
00749 for (std::string::const_iterator cIt = v.begin(); cIt != v.end(); ++cIt)
00750 {
00751 const char & c = *cIt;
00752 if (c == '&')
00753 out << "&";
00754 else
00755 out << c;
00756 }
00757 out << '\'';
00758 }
00759 }
00760 else
00761 out << '\'' << v << '\'';
00762 }
00763 }
00764
00765
00766