doc: clarified btardump help, and added btardump.1 manpage
[barry.git] / src / parser.h
blobec7e463f38ad2b16598b6625be05d0efb64bad20
1 ///
2 /// \file parser.h
3 /// Virtual parser wrapper
4 ///
6 /*
7 Copyright (C) 2005-2010, 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 "dll.h"
26 #include "data.h"
27 #include "protocol.h"
28 #include <stdint.h> // for uint32_t
29 #include <iosfwd>
30 #include <map>
32 // forward declarations
33 namespace Barry {
34 class IConverter;
35 class Contact;
36 class Message;
37 class Calendar;
38 class CalendarAll;
39 class CallLog;
40 class ServiceBook;
41 class Memo;
42 class Task;
43 class PINMessage;
44 class SavedMessage;
45 class Sms;
46 class Folder;
47 class Timezone;
50 namespace Barry {
53 // Parser class
55 /// Base class for the parser hierarchy.
56 ///
57 /// This class provides the interface that the Controller class uses
58 /// to pass raw data it reads from the device. The Controller, along
59 /// with the Packet class, calls each of the virtual functions below
60 /// in the same order.
61 ///
62 /// This class is kept as a pure abstract class, in order to make sure
63 /// that the compiler will catch any API changes, for code derived
64 /// from it.
65 ///
66 class BXEXPORT Parser
68 public:
69 Parser() {}
70 virtual ~Parser() {}
72 /// Called to parse sub fields in the raw data packet.
73 virtual void ParseRecord(const DBData &data, const IConverter *ic) = 0;
78 // NullParser class
80 /// If in debug mode, this class can be used as a null parser.
81 /// Call Init() and the protocol will be dumped to stdout and
82 /// no parsing will be done.
83 ///
84 /// Do NOT derive your own personal parser classes from this,
85 /// unless you are perfectly confident that you will catch
86 /// future API changes on the devel tree without the compiler's
87 /// help.
88 ///
89 class BXEXPORT NullParser : public Parser
91 public:
92 NullParser() {}
93 virtual ~NullParser() {}
95 virtual void ParseRecord(const DBData &data, const IConverter *ic) {}
99 // HexDumpParser
101 /// Dumps raw hex of the given DBData to the given stream.
103 /// Do NOT derive your own personal parser classes from this,
104 /// unless you are perfectly confident that you will catch
105 /// future API changes on the devel tree without the compiler's
106 /// help.
108 class BXEXPORT HexDumpParser : public Parser
110 std::ostream &m_os;
112 public:
113 explicit HexDumpParser(std::ostream &os);
115 virtual void ParseRecord(const Barry::DBData &data,
116 const IConverter *ic);
120 // RecordParserBase
122 /// Abstract base class for the following RecordParser template, that exposes
123 /// some information on the specifics that the record parser can handle.
124 /// Specifically, it exposes the database name it is able to parse
126 class BXEXPORT RecordParserBase : public Parser
128 public:
129 // These functions are always valid, regardless of the
130 // state of the parser.
131 virtual const char * GetDBName() const = 0;
132 virtual uint8_t GetDefaultRecType() const = 0;
134 // These functions depend on the parser having just parsed
135 // a record successfully.
136 virtual bool IsRecordValid() const = 0;
137 virtual uint8_t GetRecType() const = 0;
138 virtual uint32_t GetUniqueId() const = 0;
139 virtual void Dump(std::ostream &os) const = 0;
144 // Note: Store classes take parsed Record objects as a functor.
145 // Parser classes deal with raw data, while Store classes deal with
146 // parsed Record objects.
150 // NullStore
152 /// A Storage class for RecordParser<> that does nothing, for the cases
153 /// where you only want to dump parsed record data to a stream.
155 template <class RecordT>
156 class NullStore
158 public:
159 void operator() (const RecordT &r)
165 // DumpStore
167 /// A Storage class for RecordParser<> that dumps the parsed record data
168 /// to the given stream.
170 template <class RecordT>
171 class DumpStore
173 std::ostream &m_os;
175 public:
176 explicit DumpStore(std::ostream &os)
177 : m_os(os)
181 void operator() (const RecordT &r)
183 r.Dump(m_os);
188 // RecordParser template class
190 /// Template class for easy creation of specific parser objects. This template
191 /// takes the following template arguments:
193 /// - RecordT: One of the record parser classes in record.h
194 /// - StorageT: A custom storage functor class. An object of this type
195 /// will be called as a function with parsed Record as an
196 /// argument. This happens on the fly as the data is retrieved
197 /// from the device over USB, so it should not block forever.
199 /// Example LoadDatabase() call:
201 /// <pre>
202 /// struct StoreContact
203 /// {
204 /// std::vector<Contact> &amp;array;
205 /// StoreContact(std::vector<Contact> &amp;a) : array(a) {}
206 /// void operator() (const Contact &amp;c)
207 /// {
208 /// array.push_back(c);
209 /// }
210 /// };
212 /// Controller con(probeResult);
213 /// con.OpenMode(Controller::Desktop);
214 /// std::vector<Contact> contactList;
215 /// StoreContact storage(contactList);
216 /// RecordParser<Contact, StoreContact> parser(storage);
217 /// con.LoadDatabase(con.GetDBID("Address Book"), parser);
218 /// </pre>
220 template <class RecordT, class StorageT>
221 class RecordParser : public RecordParserBase
223 StorageT *m_store;
224 bool m_owned;
225 RecordT m_rec;
226 bool m_record_valid;
228 public:
229 /// Constructor that references an externally managed storage object.
230 RecordParser(StorageT &storage)
231 : m_store(&storage)
232 , m_owned(false)
233 , m_record_valid(false)
237 /// Constructor that references a locally managed storage object.
238 /// The pointer passed in will be stored, and freed when this class
239 /// is destroyed. It is safe to call this constructor with
240 /// a 'new'ly created storage object.
241 RecordParser(StorageT *storage = 0)
242 : m_store(storage)
243 , m_owned(true)
244 , m_record_valid(false)
248 ~RecordParser()
250 if( this->m_owned )
251 delete m_store;
254 virtual StorageT* GetStore()
256 return m_store;
259 virtual const StorageT* GetStore() const
261 return m_store;
264 virtual void ParseRecord(const DBData &data, const IConverter *ic)
266 m_rec = RecordT();
267 m_record_valid = false;
269 m_rec.SetIds(data.GetRecType(), data.GetUniqueId());
270 size_t offset = data.GetOffset();
271 m_rec.ParseHeader(data.GetData(), offset);
272 m_rec.ParseFields(data.GetData(), offset, ic);
273 m_record_valid = true;
275 if( m_store )
276 (*m_store)(m_rec);
280 // RecordParserBase overrides
283 // These functions are always valid, regardless of the
284 // state of the parser.
285 virtual const char * GetDBName() const
287 return RecordT::GetDBName();
290 virtual uint8_t GetDefaultRecType() const
292 return RecordT::GetDefaultRecType();
295 // These functions depend on the parser having just parsed
296 // a record successfully.
297 virtual bool IsRecordValid() const
299 return m_record_valid;
302 virtual uint8_t GetRecType() const
304 return m_rec.GetRecType();
307 virtual uint32_t GetUniqueId() const
309 return m_rec.GetUniqueId();
312 virtual void Dump(std::ostream &os) const
314 m_rec.Dump(os);
319 // MultiRecordParser
321 /// Container parser class that accepts multiple Parser objects
322 /// (often RecordParser<> objects but they don't have to be) and
323 /// automatically routes incoming records to the appropriate parser.
324 /// Note that this container owns *all* Parser objects, and will
325 /// free them upon destruction.
327 /// Incoming records that have no matching parser are passed to the
328 /// default parser object, if one exists, otherwise they are dropped
329 /// silently. The default parser object is also owned by the container,
330 /// and will be freed on destruction.
332 /// Do NOT derive your own personal parser classes from this,
333 /// unless you are perfectly confident that you will catch
334 /// future API changes on the devel tree without the compiler's
335 /// help.
337 class BXEXPORT MultiRecordParser : public Parser
339 typedef std::map<std::string, Parser*> map_type;
341 Parser *m_default;
342 map_type m_parsers;
344 public:
345 // takes ownership of default_parser!
346 explicit MultiRecordParser(Parser *default_parser = 0);
347 ~MultiRecordParser();
349 /// Adds given parser to list and takes ownership of it
350 void Add(const std::string &dbname, Parser *parser);
352 /// Adds given parser to list and takes ownership of it
353 void Add(RecordParserBase *parser);
355 /// Creates a RecordParser<> object for the given database name,
356 /// using DumpStore<> with the given stream for the output,
357 /// and adds it to list.
358 /// Returns false if there is no known Record class for dbname.
359 bool Add(const std::string &dbname, std::ostream &os);
361 // Parser overrides
362 virtual void ParseRecord(const DBData &data, const IConverter *ic);
366 // AllRecordStore
368 /// Base class with overloaded functor behaviour for all available
369 /// record classes. To be used with AllRecordParser.
371 class BXEXPORT AllRecordStore
373 public:
374 AllRecordStore() {}
375 virtual ~AllRecordStore() {}
377 virtual void operator() (const Barry::Contact &) = 0;
378 virtual void operator() (const Barry::Message &) = 0;
379 virtual void operator() (const Barry::Calendar &) = 0;
380 virtual void operator() (const Barry::CalendarAll &) = 0;
381 virtual void operator() (const Barry::CallLog &) = 0;
382 virtual void operator() (const Barry::ServiceBook &) = 0;
383 virtual void operator() (const Barry::Memo &) = 0;
384 virtual void operator() (const Barry::Task &) = 0;
385 virtual void operator() (const Barry::PINMessage &) = 0;
386 virtual void operator() (const Barry::SavedMessage &) = 0;
387 virtual void operator() (const Barry::Sms &) = 0;
388 virtual void operator() (const Barry::Folder &) = 0;
389 virtual void operator() (const Barry::Timezone &) = 0;
393 // AllRecordDumpStore
395 /// Derived from AllRecordStore, which just calls each record's
396 /// Dump() member with the given stream.
398 class BXEXPORT AllRecordDumpStore : public AllRecordStore
400 std::ostream &m_os;
402 public:
403 explicit AllRecordDumpStore(std::ostream &os)
404 : m_os(os)
408 virtual void operator() (const Barry::Contact &);
409 virtual void operator() (const Barry::Message &);
410 virtual void operator() (const Barry::Calendar &);
411 virtual void operator() (const Barry::CalendarAll &);
412 virtual void operator() (const Barry::CallLog &);
413 virtual void operator() (const Barry::ServiceBook &);
414 virtual void operator() (const Barry::Memo &);
415 virtual void operator() (const Barry::Task &);
416 virtual void operator() (const Barry::PINMessage &);
417 virtual void operator() (const Barry::SavedMessage &);
418 virtual void operator() (const Barry::Sms &);
419 virtual void operator() (const Barry::Folder &);
420 virtual void operator() (const Barry::Timezone &);
424 // AllRecordParser
426 /// Convenience parser that creates a MultiRecordParser with all known
427 /// record parsers added. If an AllRecordStore pointer is passed in,
428 /// this class takes ownership of it, and uses it as the store object
429 /// for all the RecordParser<> objects it creates. If not, then
430 /// a custom DumpStore<> object is created with the given stream
431 /// for each RecordParser<> added.
433 /// The default parser object behaves just like MultiRecordParser
435 /// This class takes ownership of all pointers passed in.
437 class BXEXPORT AllRecordParser : public MultiRecordParser
439 AllRecordStore *m_store;
441 public:
442 // takes ownership of default_parser and store!
443 explicit AllRecordParser(std::ostream &os,
444 Parser *default_parser = 0,
445 AllRecordStore *store = 0);
446 ~AllRecordParser();
450 // TeeParser
452 /// Sends incoming DBData objects to all the parsers in its list.
453 /// This parser container does NOT own the parsers added.
455 class BXEXPORT TeeParser : public Parser
457 typedef std::vector<Parser*> parser_list_type;
459 parser_list_type m_external_parsers, m_owned_parsers;
461 public:
462 TeeParser();
463 ~TeeParser();
465 /// Adds parser to internal list, and takes ownership of the
466 /// pointer.
467 void Add(Parser *p);
469 /// Adds parser to internal list. Does NOT own the parser reference.
470 void Add(Parser &p);
472 void ParseRecord(const DBData &data, const IConverter *ic);
475 } // namespace Barry
477 #endif