bool OBMoleculeFormat::OutputDeferredMols(OBConversion* pConv) { std::map<std::string, OBMol*>::iterator itr, lastitr; bool ret=false; int i=1; lastitr = IMols.end(); --lastitr; pConv->SetOneObjectOnly(false); for(itr=IMols.begin();itr!=IMols.end();++itr,++i) { if(!(itr->second)->DoTransformations(pConv->GetOptions(OBConversion::GENOPTIONS))) continue; pConv->SetOutputIndex(i); if(itr==lastitr) pConv->SetOneObjectOnly(); //to set IsLast std::string auditMsg = "OpenBabel::Write molecule "; std::string description((pConv->GetOutFormat())->Description()); auditMsg += description.substr(0,description.find('\n')); obErrorLog.ThrowError(__FUNCTION__, auditMsg, obAuditMsg); ret = pConv->GetOutFormat()->WriteMolecule(itr->second, pConv); delete itr->second; //always delete OBMol object itr->second = NULL; // so can be deleted in DeleteDeferredMols() if (!ret) break; } DeleteDeferredMols();//cleans up in case there have been errors return ret; }
bool OBMoleculeFormat::OutputDeferredMols(OBConversion* pConv) { std::map<std::string, OBMol*>::iterator itr, lastitr; bool ret=false; int i=1; lastitr = IMols.end(); --lastitr; pConv->SetOneObjectOnly(false); for(itr=IMols.begin();itr!=IMols.end();++itr,++i) { if(!(itr->second)->DoTransformations(pConv->GetOptions(OBConversion::GENOPTIONS), pConv)) continue; pConv->SetOutputIndex(i); if(itr==lastitr) pConv->SetOneObjectOnly(); //to set IsLast ret = pConv->GetOutFormat()->WriteMolecule(itr->second, pConv); delete itr->second; //always delete OBMol object itr->second = NULL; // so can be deleted in DeleteDeferredMols() if (!ret) break; } DeleteDeferredMols();//cleans up in case there have been errors return ret; }
/*! Instead of sending molecules for output via AddChemObject(), they are saved in here in OBMoleculeFormat or discarded. By default they are saved only if they are in the first input file. Parts of subsequent molecules, such as chemical structure, coordinates and OBGenericData can replace the parts in molecules with the same title that have already been stored, subject to a set of rules. After all input files have been read, the stored molecules (possibly now having augmented properties) are sent to the output format. Is a static function with *this as parameter so that it can be called from other format classes like XMLMoleculeFormat which are not derived from OBMoleculeFormat. */ bool OBMoleculeFormat::DeferMolOutput(OBMol* pmol, OBConversion* pConv, OBFormat* pF ) { static bool IsFirstFile; bool OnlyMolsInFirstFile=true; if(pConv->IsFirstInput()) { IsFirstFile=true; IMols.clear(); } else { if((std::streamoff)pConv->GetInStream()->tellg()<=0) IsFirstFile=false;//File has changed } if (!pF->ReadMolecule(pmol,pConv)) { delete pmol; return false; } const char* ptitle = pmol->GetTitle(); if(*ptitle==0) obErrorLog.ThrowError(__FUNCTION__, "Molecule with no title ignored", obWarning); else { string title(ptitle); string::size_type pos = title.find_first_of("\t\r\n"); //some title have other data appended if(pos!=string::npos) title.erase(pos); map<std::string, OBMol*>::iterator itr; itr = IMols.find(title); if(itr!=IMols.end()) { //Molecule with the same title has been input previously: update it OBMol* pNewMol = MakeCombinedMolecule(itr->second, pmol); if(pNewMol) { delete itr->second; IMols[title] = pNewMol; } else { //error: cleanup and return false delete pmol; return DeleteDeferredMols(); } } else { //Molecule not already saved in IMols: save it if in first file if(!OnlyMolsInFirstFile || IsFirstFile) { IMols[title] = pmol; return true; //don't delete pmol } } } delete pmol; return true; }