1 #ifndef __STRUCT_CMT_READER_HPP_INCLUDED__
2 #define __STRUCT_CMT_READER_HPP_INCLUDED__
3 
4 #include <corelib/ncbistl.hpp>
5 #include <corelib/ncbiobj.hpp>
6 
7 BEGIN_NCBI_SCOPE
8 
9 // forward declarations
10 namespace objects
11 {
12     class CSeq_descr;
13     class CSeqdesc;
14     class CSeq_id;
15     class CUser_object;
16     class ILineErrorListener;
17 }
18 
19 class CSerialObject;
20 class ILineReader;
21 
22 /*
23   Usage examples
24 
25   CStructuredCommentsReader reader(error_logger);
26 
27   std::list<CStructuredCommentsReader::CStructComment> comments;
28 
29   ILineReader reader1(ILineReader::New(filename);
30   reader.LoadComments(reader1, comments);
31 
32   for (const CStructuredCommentsReader::CStructComment& cmt: comments)
33   {
34      // do something
35   }
36 */
37 
38 class NCBI_XOBJREAD_EXPORT CStructuredCommentsReader
39 {
40 public:
41    // If you need messages and error to be logged
42    // supply an optional ILineErrorListener instance
43    CStructuredCommentsReader(objects::ILineErrorListener* logger);
44    ~CStructuredCommentsReader();
45 
46    class NCBI_XOBJREAD_EXPORT CStructComment
47    {
48    public:
49        CRef<objects::CSeq_id> m_id;
50        vector<CRef<objects::CSeqdesc> > m_descs;
51        static const string& GetPrefix(const objects::CSeqdesc&);
52    };
53 
54    template<typename _container>
LoadComments(ILineReader & reader,_container & cont,objects::CSeq_id::TParseFlags seqid_flags=objects::CSeq_id::fParse_Default)55    size_t LoadComments(ILineReader& reader, _container& cont,
56             objects::CSeq_id::TParseFlags seqid_flags = objects::CSeq_id::fParse_Default)
57    {
58        vector<string> cols;
59        _LoadHeaderLine(reader, cols);
60        if (cols.empty())
61            return 0;
62 
63        while (!reader.AtEOF())
64        {
65            reader.ReadLine();
66            // First line is a collumn definitions
67            CTempString current = reader.GetCurrentLine();
68            if (current.empty())
69                continue;
70 
71            // Each line except first is a set of values, first collumn is a sequence id
72            vector<CTempString> values;
73            NStr::Split(current, "\t", values);
74            if (!values[0].empty())
75            {
76                // try to find destination sequence
77                cont.push_back(CStructComment());
78                CStructComment& cmt = cont.back();
79                cmt.m_id.Reset(new objects::CSeq_id(values[0], seqid_flags));
80                _BuildStructuredComment(cmt, cols, values);
81            }
82        }
83        return cont.size();
84    }
85 
LoadCommentsByRow(ILineReader & reader,CStructComment & cmt)86    size_t LoadCommentsByRow(ILineReader& reader, CStructComment& cmt)
87    {
88        objects::CUser_object* user = 0;
89 
90        while (!reader.AtEOF())
91        {
92            reader.ReadLine();
93            // First line is a collumn definitions
94            CTempString current = reader.GetCurrentLine();
95            if (current.empty())
96                continue;
97 
98            CTempString commentname, comment;
99            NStr::SplitInTwo(current, "\t", commentname, comment);
100 
101            // create new user object
102            user = _AddStructuredComment(user, cmt, commentname, comment);
103        }
104        return cmt.m_descs.size();
105    }
106 
107 
108 protected:
109    void _LoadHeaderLine(ILineReader& reader, vector<string>& cols);
110    void _BuildStructuredComment(CStructComment& cmt, const vector<string>& cols, const vector<CTempString>& values);
111    objects::CUser_object* _AddStructuredComment(objects::CUser_object* user_obj, CStructComment& cmt, const CTempString& name, const CTempString& value);
112    objects::ILineErrorListener* m_logger;
113 };
114 
115 END_NCBI_SCOPE
116 
117 
118 #endif
119