📄 asn2asn.cpp
字号:
auto_ptr<CArgDescriptions> d(new CArgDescriptions); d->SetUsageContext("asn2asn", "convert Seq-entry or Bioseq-set data"); d->AddKey("i", "inputFile", "input data file", CArgDescriptions::eInputFile); d->AddOptionalKey("o", "outputFile", "output data file", CArgDescriptions::eOutputFile); d->AddFlag("e", "treat data as Seq-entry"); d->AddFlag("b", "binary ASN.1 input format"); d->AddFlag("X", "XML input format"); d->AddFlag("s", "binary ASN.1 output format"); d->AddFlag("x", "XML output format"); d->AddFlag("C", "Convert data without reading in memory"); d->AddFlag("S", "Skip data without reading in memory"); d->AddOptionalKey("l", "logFile", "log errors to <logFile>", CArgDescriptions::eOutputFile); d->AddDefaultKey("c", "count", "perform command <count> times", CArgDescriptions::eInteger, "1"); d->AddDefaultKey("tc", "threadCount", "perform command in <threadCount> thread", CArgDescriptions::eInteger, "1"); d->AddFlag("ih", "Use read hooks"); d->AddFlag("oh", "Use write hooks"); d->AddFlag("q", "Quiet execution"); SetupArgDescriptions(d.release());}class CAsn2AsnThread : public CThread{public: CAsn2AsnThread(int index, CAsn2Asn* asn2asn) : m_Index(index), m_Asn2Asn(asn2asn), m_DoneOk(false) { } void* Main() { string suffix = '.'+NStr::IntToString(m_Index); try { m_Asn2Asn->RunAsn2Asn(suffix); } catch (exception& e) { CNcbiDiag() << Error << "[asn2asn thread " << m_Index << "]" << "Exception: " << e.what(); return 0; } m_DoneOk = true; return 0; } bool DoneOk() const { return m_DoneOk; }private: int m_Index; CAsn2Asn* m_Asn2Asn; bool m_DoneOk;};int CAsn2Asn::Run(void){ SetDiagPostLevel(eDiag_Error); const CArgs& args = GetArgs(); if ( const CArgValue& l = args["l"] ) SetDiagStream(&l.AsOutputFile()); size_t threadCount = args["tc"].AsInteger(); vector< CRef<CAsn2AsnThread> > threads(threadCount); for ( size_t i = 1; i < threadCount; ++i ) { threads[i] = new CAsn2AsnThread(i, this); threads[i]->Run(); } try { RunAsn2Asn(""); } catch (exception& e) { CNcbiDiag() << Error << "[asn2asn]" << "Exception: " << e.what(); return 1; } for ( size_t i = 1; i < threadCount; ++i ) { threads[i]->Join(); if ( !threads[i]->DoneOk() ) { NcbiCerr << "Error in thread: " << i << NcbiEndl; return 1; } } return 0;}DEFINE_STATIC_FAST_MUTEX(s_ArgsMutex);void CAsn2Asn::RunAsn2Asn(const string& outFileSuffix){ CFastMutexGuard GUARD(s_ArgsMutex); const CArgs& args = GetArgs(); string inFile = args["i"].AsString(); ESerialDataFormat inFormat = eSerial_AsnText; if ( args["b"] ) inFormat = eSerial_AsnBinary; else if ( args["X"] ) inFormat = eSerial_Xml; const CArgValue& o = args["o"]; bool haveOutput = o; string outFile; ESerialDataFormat outFormat = eSerial_AsnText; if ( haveOutput ) { outFile = o.AsString(); if ( args["s"] ) outFormat = eSerial_AsnBinary; else if ( args["x"] ) outFormat = eSerial_Xml; } outFile += outFileSuffix; bool inSeqEntry = args["e"]; bool skip = args["S"]; bool convert = args["C"]; bool readHook = args["ih"]; bool writeHook = args["oh"]; bool quiet = args["q"]; size_t count = args["c"].AsInteger(); GUARD.Release(); for ( size_t i = 1; i <= count; ++i ) { bool displayMessages = count != 1 && !quiet; if ( displayMessages ) NcbiCerr << "Step " << i << ':' << NcbiEndl; auto_ptr<CObjectIStream> in(CObjectIStream::Open(inFormat, inFile, eSerial_StdWhenAny)); auto_ptr<CObjectOStream> out(!haveOutput? 0: CObjectOStream::Open(outFormat, outFile, eSerial_StdWhenAny)); if ( inSeqEntry ) { /* read one Seq-entry */ if ( skip ) { if ( displayMessages ) NcbiCerr << "Skipping Seq-entry..." << NcbiEndl; in->Skip(CType<CSeq_entry>()); } else if ( convert && haveOutput ) { if ( displayMessages ) NcbiCerr << "Copying Seq-entry..." << NcbiEndl; CObjectStreamCopier copier(*in, *out); copier.Copy(CType<CSeq_entry>()); } else { TSeqEntry entry; //entry.DoNotDeleteThisObject(); if ( displayMessages ) NcbiCerr << "Reading Seq-entry..." << NcbiEndl; *in >> entry; SeqEntryProcess(entry); /* do any processing */ if ( haveOutput ) { if ( displayMessages ) NcbiCerr << "Writing Seq-entry..." << NcbiEndl; *out << entry; } } } else { /* read Seq-entry's from a Bioseq-set */ if ( skip ) { if ( displayMessages ) NcbiCerr << "Skipping Bioseq-set..." << NcbiEndl; in->Skip(CType<CBioseq_set>()); } else if ( convert && haveOutput ) { if ( displayMessages ) NcbiCerr << "Copying Bioseq-set..." << NcbiEndl; CObjectStreamCopier copier(*in, *out); copier.Copy(CType<CBioseq_set>()); } else { CBioseq_set entries; //entries.DoNotDeleteThisObject(); if ( displayMessages ) NcbiCerr << "Reading Bioseq-set..." << NcbiEndl; if ( readHook ) { CObjectTypeInfo bioseqSetType = CType<CBioseq_set>(); bioseqSetType.FindMember("seq-set") .SetLocalReadHook(*in, new CReadSeqSetHook); *in >> entries; } else { *in >> entries; NON_CONST_ITERATE ( CBioseq_set::TSeq_set, seqi, entries.SetSeq_set() ) { SeqEntryProcess(**seqi); /* do any processing */ } } if ( haveOutput ) { if ( displayMessages ) NcbiCerr << "Writing Bioseq-set..." << NcbiEndl; if ( writeHook ) {#if 0 CObjectTypeInfo bioseqSetType = CType<CBioseq_set>(); bioseqSetType.FindMember("seq-set") .SetLocalWriteHook(*out, new CWriteSeqSetHook);#else CObjectTypeInfo seqEntryType = CType<CSeq_entry>(); seqEntryType .SetLocalWriteHook(*out, new CWriteSeqEntryHook);#endif *out << entries; } else { *out << entries; } } } } }}/******************************************************************************* void SeqEntryProcess (sep)* just a dummy routine that does nothing******************************************************************************/staticvoid SeqEntryProcess(CSeq_entry& /* seqEntry */){}void CReadSeqSetHook::ReadClassMember(CObjectIStream& in, const CObjectInfo::CMemberIterator& member){ CInc inc(m_Level); if ( m_Level == 1 ) { // (do not have to read member open/close tag, it's done by this time) // Read each element separately to a local TSeqEntry, // process it somehow, and... not store it in the container. for ( CIStreamContainerIterator i(in, member); i; ++i ) { TSeqEntry entry; //entry.DoNotDeleteThisObject(); i >> entry; SeqEntryProcess(entry); } // MemberIterators are DANGEROUS! -- do not use the following // unless... // The same trick can be done with CIStreamClassMember -- to traverse // through the class members rather than container elements. // CObjectInfo object = member; // for ( CIStreamClassMemberIterator i(in, object); i; ++i ) { // // CObjectTypeInfo::CMemberIterator nextMember = *i; // in.ReadObject(object.GetMember(*i)); // } } else { // standard read in.ReadClassMember(member); }}void CWriteSeqEntryHook::WriteObject(CObjectOStream& out, const CConstObjectInfo& object){ CInc inc(m_Level); if ( m_Level == 1 ) { NcbiCerr << "entry" << NcbiEndl; // const CSeq_entry& entry = *CType<CSeq_entry>::Get(object); object.GetTypeInfo()->DefaultWriteData(out, object.GetObjectPtr()); } else { // const CSeq_entry& entry = *CType<CSeq_entry>::Get(object); object.GetTypeInfo()->DefaultWriteData(out, object.GetObjectPtr()); }}void CWriteSeqSetHook::WriteClassMember(CObjectOStream& out, const CConstObjectInfo::CMemberIterator& member){ // keep track of the level of write recursion CInc inc(m_Level); // just for fun -- do the hook only on the first level of write recursion, if ( m_Level == 1 ) { // provide opening and closing(automagic, in destr) tags for the member COStreamClassMember m(out, member); // out.WriteObject(*member); or, with just the same effect: // provide opening and closing(automagic) tags for the container COStreamContainer o(out, member); typedef CBioseq_set::TSeq_set TSeq_set; // const TSeq_set& cnt = *CType<TSeq_set>::Get(*member); // but as soon as we know for sure that it *is* TSeq_set, so: const TSeq_set& cnt = *CType<TSeq_set>::GetUnchecked(*member); // write elem-by-elem for ( TSeq_set::const_iterator i = cnt.begin(); i != cnt.end(); ++i ) { const TSeqEntry& entry = **i; // COStreamContainer is smart enough to automagically put // open/close tags for each element written o << entry; // here, we could e.g. write each elem twice: // o << entry; o << entry; // we cannot change the element content as everything is const in // the write hooks. } } else { // on all other levels -- use standard write func for this member out.WriteClassMember(member); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -