void CDate_std::GetDate(string* label, const string& format) const { static const char* const kMonths[] = { "0", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; static const int kNumMonths = sizeof (kMonths) / sizeof (char*); if (!label) { return; } unsigned int depth = 0; vector<pair<SIZE_TYPE, SIZE_TYPE> > starts; starts.push_back(make_pair(label->size(), (SIZE_TYPE)0)); ITERATE (string, it, format) { if (*it != '%') { *label += *it; continue; } if (++it == format.end()) { NCBI_THROW2(CGeneralParseException, eFormat, "CDate_std::GetDate(): incomplete % expression", it - format.begin()); } // Check for things that can only immediately follow % if (*it == '%') { *label += '%'; continue; } else if (*it == '{') { depth++; starts.push_back(make_pair(label->size(), SIZE_TYPE(it - format.begin()))); continue; } else if (*it == '}') { if (depth == 0) { NCBI_THROW2(CGeneralParseException, eFormat, "CDate_std::GetDate(): unbalanced %}", it - format.begin()); } depth--; starts.pop_back(); continue; } else if (*it == '|') { // We survived, so just look for the appropriate %}. if (depth == 0) { return; // Can ignore rest of format } unsigned int depth2 = 0; for (;;) { while (++it != format.end() && *it != '%') ; if (it == format.end() || ++it == format.end()) { NCBI_THROW2(CGeneralParseException, eFormat, "CDate_std::GetDate(): unbalanced %{", starts.back().second); } if (*it == '}') { if (depth2 == 0) { depth--; starts.pop_back(); break; } else { depth2--; } } else if (*it == '{') { depth2++; } } continue; } unsigned int length = 0; int value = -1; while (isdigit((unsigned char)(*it))) { length = length * 10 + *it - '0'; if (++it == format.end()) { NCBI_THROW2(CGeneralParseException, eFormat, "CDate_std::GetDate(): incomplete % expression", it - format.begin()); } } switch (*it) { case 'Y': value = GetYear(); break; case 'M': case 'N': value = CanGetMonth() ? GetMonth() : -1; break; case 'D': value = CanGetDay() ? GetDay() : -1; break; case 'S': value = CanGetSeason() ? 1 : -1; break; case 'h': value = CanGetHour() ? GetHour() : -1; break; case 'm': value = CanGetMinute() ? GetMinute() : -1; break; case 's': value = CanGetSecond() ? GetSecond() : -1; break; default: NCBI_THROW2(CGeneralParseException, eFormat, "CDate_std::GetDate(): unrecognized format specifier", it - format.begin()); } if (value >= 0) { if (*it == 'N') { // special cases const char* name; if (value >= kNumMonths) { name = "inv"; } else { name = kMonths[value]; } if (length > 0) { label->append(name, length); } else { *label += name; } } else if (*it == 'S') { if (length > 0) { label->append(GetSeason(), 0, length); } else { *label += GetSeason(); } } else { // just a number if (length > 0) { // We want exactly <length> digits. CNcbiOstrstream oss; oss << setfill('0') << setw(length) << value; string s = CNcbiOstrstreamToString(oss); label->append(s, s.size() > length ? s.size() - length : 0, length); } else { *label += NStr::IntToString(value); } } } else { // missing...roll back label and look for alternatives, or // throw if at top level and none found label->erase(starts.back().first); char request = *it; unsigned int depth2 = 0; for (;;) { while (++it != format.end() && *it != '%') ; if (it == format.end() || ++it == format.end()) { if (depth > 0 || depth2 > 0) { NCBI_THROW2(CGeneralParseException, eFormat, "CDate_std::GetDate(): unbalanced %{", starts.back().second); } else { NCBI_THROW2(CGeneralParseException, eFormat, string("CDate_std::GetDate():" " missing required field %") + request, it - format.begin() - 1); } } if (*it == '|' && depth2 == 0) { break; } else if (*it == '}') { if (depth2 == 0) { if (depth == 0) { NCBI_THROW2(CGeneralParseException, eFormat, "CDate_std::GetDate(): unbalanced %}", it - format.begin()); } depth--; starts.pop_back(); break; } else { depth2--; } } else if (*it == '{') { depth2++; } } } } }
CRef<CBioseq_set> CMakeCdrProds::MakeCdrProds(CRef<CSeq_annot> annot, CBioseq_Handle handle) { CRef<CBioseq_set> bioseq_set(new CBioseq_set); if (!annot->GetData().IsFtable()) { // Is this the right thing to do? // Could throw, or could return null CRef instead. return bioseq_set; } list<CRef<CSeq_feat> >& ftable = annot->SetData().SetFtable(); NON_CONST_ITERATE (list<CRef<CSeq_feat> >, feat, ftable) { if (!(*feat)->GetData().IsCdregion()) { // not interested if not a Cdregion continue; } if ((*feat)->IsSetProduct()) { // already has a product; don't make new one continue; } string prot; CSeqTranslator::Translate(**feat, handle.GetScope(), prot); CRef<CSeq_data> seq_data(new CSeq_data(prot, CSeq_data::e_Iupacaa)); CRef<CSeq_inst> seq_inst(new CSeq_inst); seq_inst->SetSeq_data(*seq_data); seq_inst->SetRepr(CSeq_inst_Base::eRepr_raw); seq_inst->SetMol(CSeq_inst_Base::eMol_aa); seq_inst->SetLength(prot.size()); CRef<CBioseq> bio_seq(new CBioseq); string num = NStr::NumericToString(sm_Counter.Add(1)); // pad to five digits if (num.size() < 5) { num.insert(SIZE_TYPE(0), 5 - num.size(), '0'); } string acc = "tp" + num; string full_acc = "lcl|" + acc; CRef<CSeq_id> id(new CSeq_id(full_acc)); bio_seq->SetId().push_back(id); // a title CRef<CSeqdesc> title(new CSeqdesc); title->SetTitle(string("Translation product ") + acc); bio_seq->SetDescr().Set().push_back(title); // Mol_type CRef<CSeqdesc> mol_type(new CSeqdesc); mol_type->SetMol_type( eGIBB_mol_peptide); bio_seq->SetDescr().Set().push_back(mol_type); // set the instance bio_seq->SetInst(*seq_inst); // wrap this Bio_seq in an entry CRef<CSeq_entry> seq_entry(new CSeq_entry); seq_entry->SetSeq(*bio_seq); // add this entry to our Bioseq_set bioseq_set->SetSeq_set().push_back(seq_entry); // record it as product in the annot we're handed CRef<CSeq_loc> prod_loc(new CSeq_loc); prod_loc->SetWhole(*id); (*feat)->SetProduct(*prod_loc); } return bioseq_set; }