- bumped version numbers to 0.8 in:
[barry.git] / src / record.h
blobd9ad50d23abed2f7bd350caa88ac26d482a7771a
1 ///
2 /// \file record.h
3 /// Blackberry database record classes. Help translate data
4 /// from data packets to useful structurs, and back.
5 ///
7 /*
8 Copyright (C) 2005-2007, Net Direct Inc. (http://www.netdirect.ca/)
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License in the COPYING file at the
20 root directory of this project for more details.
23 #ifndef __BARRY_RECORD_H__
24 #define __BARRY_RECORD_H__
26 #include <iosfwd>
27 #include <string>
28 #include <vector>
29 #include <map>
30 #include <stdint.h>
32 // forward declarations
33 namespace Barry { class Data; }
35 namespace Barry {
38 // NOTE: All classes here must be container-safe! Perhaps add sorting
39 // operators in the future.
44 class CommandTable
46 public:
47 struct Command
49 unsigned int Code;
50 std::string Name;
53 typedef std::vector<Command> CommandArrayType;
55 CommandArrayType Commands;
57 private:
58 const unsigned char* ParseField(const unsigned char *begin,
59 const unsigned char *end);
60 public:
61 CommandTable();
62 ~CommandTable();
64 void Parse(const Data &data, size_t offset);
65 void Clear();
67 // returns 0 if unable to find command name, which is safe, since
68 // 0 is a special command that shouldn't be in the table anyway
69 unsigned int GetCommand(const std::string &name) const;
71 void Dump(std::ostream &os) const;
74 inline std::ostream& operator<< (std::ostream &os, const CommandTable &command) {
75 command.Dump(os);
76 return os;
81 class RecordStateTable
83 public:
84 struct State
86 unsigned int Index;
87 uint32_t RecordId;
88 bool Dirty;
89 unsigned int RecType;
90 std::string Unknown2;
93 typedef unsigned int IndexType;
94 typedef std::map<IndexType, State> StateMapType;
96 StateMapType StateMap;
98 private:
99 mutable IndexType m_LastNewRecordId;
101 private:
102 const unsigned char* ParseField(const unsigned char *begin,
103 const unsigned char *end);
105 public:
106 RecordStateTable();
107 ~RecordStateTable();
109 void Parse(const Data &data);
110 void Clear();
112 bool GetIndex(uint32_t RecordId, IndexType *pFoundIndex = 0) const;
113 uint32_t MakeNewRecordId() const;
115 void Dump(std::ostream &os) const;
118 inline std::ostream& operator<< (std::ostream &os, const RecordStateTable &rst) {
119 rst.Dump(os);
120 return os;
125 class DatabaseDatabase
127 public:
128 struct Database
130 unsigned int Number;
131 unsigned int RecordCount;
132 std::string Name;
135 typedef std::vector<Database> DatabaseArrayType;
137 DatabaseArrayType Databases;
139 private:
140 template <class RecordType, class FieldType>
141 void ParseRec(const RecordType &rec, const unsigned char *end);
143 template <class FieldType>
144 const unsigned char* ParseField(const unsigned char *begin,
145 const unsigned char *end);
147 public:
148 DatabaseDatabase();
149 ~DatabaseDatabase();
151 void Parse(const Data &data);
152 void Clear();
154 // returns true on success, and fills target
155 bool GetDBNumber(const std::string &name, unsigned int &number) const;
156 bool GetDBName(unsigned int number, std::string &name) const;
158 void Dump(std::ostream &os) const;
161 inline std::ostream& operator<<(std::ostream &os, const DatabaseDatabase &dbdb) {
162 dbdb.Dump(os);
163 return os;
168 struct UnknownField
170 uint8_t type;
171 std::string data;
173 std::ostream& operator<< (std::ostream &os, const std::vector<UnknownField> &unknowns);
176 /// \addtogroup RecordParserClasses
177 /// Parser and data storage classes. These classes take a
178 /// Database Database record and convert them into C++ objects.
179 /// Each of these classes are safe to be used in standard
180 /// containers, and are meant to be used in conjunction with the
181 /// RecordParser<> template when calling Controller::LoadDatabase().
182 /// @{
184 class Contact
186 public:
187 struct GroupLink
189 uint32_t Link;
190 uint16_t Unknown;
192 GroupLink() : Link(0), Unknown(0) {}
193 GroupLink(uint32_t link, uint16_t unknown)
194 : Link(link), Unknown(unknown)
198 typedef std::vector<GroupLink> GroupLinksType;
199 typedef std::vector<UnknownField> UnknownsType;
201 // contact specific data
202 uint8_t RecType;
203 uint32_t RecordId;
204 std::string
205 Email,
206 Phone,
207 Fax,
208 WorkPhone,
209 HomePhone,
210 MobilePhone,
211 Pager,
212 PIN,
213 FirstName,
214 LastName,
215 Company,
216 DefaultCommunicationsMethod,
217 Address1,
218 Address2,
219 Address3,
220 City,
221 Province,
222 PostalCode,
223 Country,
224 Title,
225 PublicKey,
226 Notes;
228 GroupLinksType GroupLinks;
229 UnknownsType Unknowns;
231 private:
232 bool m_FirstNameSeen;
234 //protected:
235 public:
236 const unsigned char* ParseField(const unsigned char *begin,
237 const unsigned char *end);
239 public:
240 Contact();
241 ~Contact();
243 uint32_t GetID() const { return RecordId; }
244 std::string GetPostalAddress() const;
246 // Parser / Builder API (see parser.h / builder.h)
247 uint8_t GetRecType() const { return RecType; }
248 uint32_t GetUniqueId() const { return RecordId; }
249 void SetIds(uint8_t Type, uint32_t Id) { RecType = Type; RecordId = Id; }
250 void ParseHeader(const Data &data, size_t &offset);
251 void ParseFields(const Data &data, size_t &offset);
252 void BuildHeader(Data &data, size_t &offset) const;
253 void BuildFields(Data &data, size_t &offset) const;
255 void Clear(); // erase everything
257 void Dump(std::ostream &os) const;
259 // sorting - put group links at the end
260 bool operator<(const Contact &other) const {
261 return GroupLinks.size() == 0 && other.GroupLinks.size() > 0;
262 // // testing - put group links at the top
263 // return GroupLinks.size() > 0 && other.GroupLinks.size() == 0;
266 // database name
267 static const char * GetDBName() { return "Address Book"; }
268 static uint8_t GetDefaultRecType() { return 0; }
270 // helpers
271 static void SplitName(const std::string &full, std::string &first, std::string &last);
274 inline std::ostream& operator<< (std::ostream &os, const Contact &contact) {
275 contact.Dump(os);
276 return os;
279 class Message
281 public:
282 struct Address
284 std::string Name;
285 std::string Email;
289 Address From;
290 Address To;
291 Address Cc;
292 std::string Subject;
293 std::string Body;
294 std::vector<UnknownField> Unknowns;
296 public:
297 const unsigned char* ParseField(const unsigned char *begin,
298 const unsigned char *end);
300 public:
301 Message();
302 ~Message();
304 // Parser / Builder API (see parser.h / builder.h)
305 uint8_t GetRecType() const;
306 uint32_t GetUniqueId() const; // empty API, not required by protocol
307 void SetIds(uint8_t Type, uint32_t Id); // empty API, not required by protocol
308 void ParseHeader(const Data &data, size_t &offset);
309 void ParseFields(const Data &data, size_t &offset);
310 void BuildHeader(Data &data, size_t &offset) const;
311 void BuildFields(Data &data, size_t &offset) const;
313 void Clear();
315 void Dump(std::ostream &os) const;
317 // sorting
318 bool operator<(const Message &other) const { return Subject < other.Subject; }
320 // database name
321 static const char * GetDBName() { return "Messages"; }
322 static uint8_t GetDefaultRecType() { return 0; }
325 inline std::ostream& operator<<(std::ostream &os, const Message &msg) {
326 msg.Dump(os);
327 return os;
330 std::ostream& operator<<(std::ostream &os, const Message::Address &msga);
333 class Calendar
335 public:
336 typedef std::vector<UnknownField> UnknownsType;
338 uint8_t RecType;
339 uint32_t RecordId;
341 // general data
342 bool AllDayEvent;
343 std::string Subject;
344 std::string Notes;
345 std::string Location;
346 time_t NotificationTime;
347 time_t StartTime;
348 time_t EndTime;
351 /// Recurring data
353 /// Note: interval can be used on all of these recurring types to
354 /// make it happen "every other time" or more, etc.
356 enum RecurringCodeType {
357 Day = 1, //< eg. every day
358 //< set: nothing
359 MonthByDate = 3, //< eg. every month on the 12th
360 //< set: DayOfMonth
361 MonthByDay = 4, //< eg. every month on 3rd Wed
362 //< set: DayOfWeek and WeekOfMonth
363 YearByDate = 5, //< eg. every year on March 5
364 //< set: DayOfMonth and MonthOfYear
365 YearByDay = 6, //< eg. every year on 3rd Wed of Jan
366 //< set: DayOfWeek, WeekOfMonth, and
367 //< MonthOfYear
368 Week = 12 //< eg. every week on Mon and Fri
369 //< set: WeekDays
372 bool Recurring;
373 RecurringCodeType RecurringType;
374 unsigned short Interval; // must be >= 1
375 time_t RecurringEndTime; // only pertains if Recurring is true
376 // sets the date and time when
377 // recurrence of this appointment
378 // should no longer occur
379 // If a perpetual appointment, this
380 // is 0xFFFFFFFF in the low level data
381 // Instead, set the following flag.
382 bool Perpetual; // if true, this will always recur
383 unsigned short TimeZoneCode; // the time zone originally used
384 // for the recurrence data...
385 // seems to have little use, but
386 // set to your current time zone
387 // as a good default
389 unsigned short // recurring details, depending on type
390 DayOfWeek, // 0-6
391 WeekOfMonth, // 1-5
392 DayOfMonth, // 1-31
393 MonthOfYear; // 1-12
394 unsigned char WeekDays; // bitmask, bit 0 = sunday
396 // FIXME - put these somewhere usable by both C and C++
397 #define CAL_WD_SUN 0x01
398 #define CAL_WD_MON 0x02
399 #define CAL_WD_TUE 0x04
400 #define CAL_WD_WED 0x08
401 #define CAL_WD_THU 0x10
402 #define CAL_WD_FRI 0x20
403 #define CAL_WD_SAT 0x40
405 // unknown
406 UnknownsType Unknowns;
408 public:
409 const unsigned char* ParseField(const unsigned char *begin,
410 const unsigned char *end);
411 void ParseRecurrenceData(const void *data);
412 void BuildRecurrenceData(void *data);
414 public:
415 Calendar();
416 ~Calendar();
418 // Parser / Builder API (see parser.h / builder.h)
419 uint8_t GetRecType() const { return RecType; }
420 uint32_t GetUniqueId() const { return RecordId; }
421 void SetIds(uint8_t Type, uint32_t Id) { RecType = Type; RecordId = Id; }
422 void ParseHeader(const Data &data, size_t &offset);
423 void ParseFields(const Data &data, size_t &offset);
424 void BuildHeader(Data &data, size_t &offset) const;
425 void BuildFields(Data &data, size_t &offset) const;
427 void Clear();
429 void Dump(std::ostream &os) const;
431 // sorting
432 bool operator<(const Calendar &other) const { return StartTime < other.StartTime; }
434 // database name
435 static const char * GetDBName() { return "Calendar"; }
436 static uint8_t GetDefaultRecType() { return 5; } // or 0?
439 inline std::ostream& operator<<(std::ostream &os, const Calendar &msg) {
440 msg.Dump(os);
441 return os;
445 // This is a packed field, which is a group of fields packed in
446 // variable length records inside one larger field of a normal record.
447 class ServiceBookConfig
449 public:
450 typedef std::vector<UnknownField> UnknownsType;
452 uint8_t Format;
454 UnknownsType Unknowns;
456 public:
457 const unsigned char* ParseField(const unsigned char *begin,
458 const unsigned char *end);
460 public:
461 ServiceBookConfig();
462 ~ServiceBookConfig();
464 // Parser / Builder API (see parser.h / builder.h)
465 void ParseHeader(const Data &data, size_t &offset);
466 void ParseFields(const Data &data, size_t &offset);
467 void BuildHeader(Data &data, size_t &offset) const;
468 void BuildFields(Data &data, size_t &offset) const;
470 void Clear();
472 void Dump(std::ostream &os) const;
475 inline std::ostream& operator<<(std::ostream &os, const ServiceBookConfig &msg) {
476 msg.Dump(os);
477 return os;
481 class ServiceBook
483 int NameType, DescType, UniqueIdType;
485 public:
486 typedef std::vector<UnknownField> UnknownsType;
488 uint8_t RecType;
489 uint32_t RecordId;
490 std::string Name;
491 std::string HiddenName;
492 std::string Description;
493 std::string DSID;
494 std::string BesDomain;
495 std::string UniqueId;
496 std::string ContentId;
497 ServiceBookConfig Config;
499 UnknownsType Unknowns;
501 public:
502 const unsigned char* ParseField(const unsigned char *begin,
503 const unsigned char *end);
505 public:
506 ServiceBook();
507 ~ServiceBook();
509 // Parser / Builder API (see parser.h / builder.h)
510 uint8_t GetRecType() const { return RecType; }
511 uint32_t GetUniqueId() const { return RecordId; }
512 void SetIds(uint8_t Type, uint32_t Id) { RecType = Type; RecordId = Id; }
513 void ParseHeader(const Data &data, size_t &offset);
514 void ParseFields(const Data &data, size_t &offset);
515 void BuildHeader(Data &data, size_t &offset) const;
516 void BuildFields(Data &data, size_t &offset) const;
518 void Clear();
520 void Dump(std::ostream &os) const;
522 // sorting
523 bool operator<(const ServiceBook &other) const { return RecordId < RecordId; }
525 // database name
526 static const char * GetDBName() { return "Service Book"; }
527 static uint8_t GetDefaultRecType() { return 0; }
530 inline std::ostream& operator<<(std::ostream &os, const ServiceBook &msg) {
531 msg.Dump(os);
532 return os;
535 /// @}
537 } // namespace Barry
539 #endif