- changed headers so that any low level protocol-specific sizes and
[barry.git] / src / parser.h
blob3134917eb5b345a5450a61c7c5da9ea413d224a6
1 ///
2 /// \file parser.h
3 /// Virtual parser wrapper
4 ///
6 /*
7 Copyright (C) 2005, Net Direct Inc. (http://www.netdirect.ca/)
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
22 #ifndef __BARRY_PARSER_H__
23 #define __BARRY_PARSER_H__
25 #include "data.h"
26 #include "protocol.h"
27 #include "debug.h"
29 namespace Barry {
31 // also acts as a null parser
33 // Parser class
35 /// Base class for the parser functor hierarchy. If in debug mode, this
36 /// class can be used as a null parser. Call Init() and the protocol
37 /// will be dumped to stdout and no parsing will be done.
38 ///
39 class Parser
41 public:
42 Parser() {}
43 virtual ~Parser() {}
45 virtual bool operator()(const Data &data) { return true; }
47 virtual bool GetOperation(const Data &data, unsigned int &operation);
48 virtual size_t GetHeaderSize(size_t recordsize) const;
53 // RecordParser template class
55 /// Template class for easy creation of specific parser objects. This template
56 /// takes the following template argumens:
57 ///
58 /// - Record: One of the record parser classes in record.h
59 /// - Storage: A custom storage functor class. An object of this type
60 /// will be called as a function with parsed Record as an
61 /// argument. This happens on the fly as the data is retrieved
62 /// from the device over USB, so it should not block forever.
63 ///
64 /// Example LoadDatabase() call:
65 ///
66 /// <pre>
67 /// struct StoreContact
68 /// {
69 /// std::vector<Contact> &amp;array;
70 /// StoreContact(std::vector<Contact> &amp;a) : array(a) {}
71 /// void operator() (const Contact &amp;c)
72 /// {
73 /// array.push_back(c);
74 /// }
75 /// };
76 ///
77 /// Controller con(probeResult);
78 /// con.OpenMode(Controller::Desktop);
79 /// std::vector<Contact> contactList;
80 /// StoreContact storage(contactList);
81 /// RecordParser<Contact, StoreContact> parser(storage);
82 /// con.LoadDatabase(con.GetDBID("Address Book"), parser);
83 /// </pre>
84 ///
85 template <class Record, class Storage>
86 class RecordParser : public Parser
88 Storage *m_store;
89 bool m_owned;
91 public:
92 /// Constructor that references an externally managed storage object.
93 RecordParser(Storage &storage)
94 : m_store(&storage), m_owned(false) {}
96 /// Constructor that references a locally managed storage object.
97 /// The pointer passed in will be stored, and freed when this class
98 /// is destroyed. It is safe to call this constructor with
99 /// a 'new'ly created storage object.
100 RecordParser(Storage *storage)
101 : m_store(storage), m_owned(true) {}
103 ~RecordParser()
105 if( this->m_owned )
106 delete m_store;
109 virtual bool CheckHeaderSize(const Data &data, unsigned int operation)
111 size_t recordsize;
112 switch( operation )
114 case SB_DBOP_GET_RECORDS:
115 // using the new protocol
116 recordsize = Record::GetProtocolRecordSize();
117 break;
119 case SB_DBOP_OLD_GET_RECORDS_REPLY:
120 // using the old protocol
121 recordsize = Record::GetOldProtocolRecordSize();
122 break;
124 default:
125 // unknown protocol
126 dout("Unknown protocol");
127 return false;
130 // return true if header is ok
131 return (size_t)data.GetSize() > GetHeaderSize(recordsize);
134 /// Functor member called by Controller::LoadDatabase() during
135 /// processing.
136 virtual bool operator()(const Data &data)
138 unsigned int operation;
139 if( !GetOperation(data, operation) )
140 return false;
141 if( !CheckHeaderSize(data, operation) )
142 return false;
144 Record rec;
145 rec.Parse(data, operation);
146 (*m_store)(rec);
147 return true;
151 } // namespace Barry
153 #endif