3 /// Blackberry database record classes. Help translate data
4 /// from data packets to useful structurs, and back.
5 /// This header provides the common types and classes
6 /// used by the general record parser classes in the
7 /// r_*.h files. Only application-safe API stuff goes in
8 /// here. Internal library types go in record-internal.h
12 Copyright (C) 2005-2012, Net Direct Inc. (http://www.netdirect.ca/)
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23 See the GNU General Public License in the COPYING file at the
24 root directory of this project for more details.
27 #ifndef __BARRY_RECORD_H__
28 #define __BARRY_RECORD_H__
38 // forward declarations
39 namespace Barry
{ class Data
; }
44 // NOTE: All classes here must be container-safe! Perhaps add sorting
45 // operators in the future.
49 // stream-based wrapper to avoid printing strings that contain
50 // the \r carriage return characters
51 class BXEXPORT Cr2LfWrapper
53 friend std::ostream
& operator<< (std::ostream
&os
, const Cr2LfWrapper
&str
);
54 const std::string
&m_str
;
56 explicit Cr2LfWrapper(const std::string
&str
)
61 BXEXPORT
std::ostream
& operator<< (std::ostream
&os
, const Cr2LfWrapper
&str
);
63 struct BXEXPORT CommandTableCommand
69 class BXEXPORT CommandTable
72 typedef CommandTableCommand Command
;
73 typedef std::vector
<Command
> CommandArrayType
;
75 CommandArrayType Commands
;
78 BXLOCAL
const unsigned char* ParseField(const unsigned char *begin
,
79 const unsigned char *end
);
84 void Parse(const Data
&data
, size_t offset
);
87 // returns 0 if unable to find command name, which is safe, since
88 // 0 is a special command that shouldn't be in the table anyway
89 unsigned int GetCommand(const std::string
&name
) const;
91 void Dump(std::ostream
&os
) const;
94 BXEXPORT
inline std::ostream
& operator<< (std::ostream
&os
, const CommandTable
&command
) {
101 struct BXEXPORT RecordStateTableState
106 unsigned int RecType
;
107 std::string Unknown2
;
110 class BXEXPORT RecordStateTable
113 typedef RecordStateTableState State
;
114 typedef unsigned int IndexType
;
115 typedef std::map
<IndexType
, State
> StateMapType
;
117 StateMapType StateMap
;
120 mutable IndexType m_LastNewRecordId
;
123 BXLOCAL
const unsigned char* ParseField(const unsigned char *begin
,
124 const unsigned char *end
);
130 void Parse(const Data
&data
);
133 bool GetIndex(uint32_t RecordId
, IndexType
*pFoundIndex
= 0) const;
134 uint32_t MakeNewRecordId() const;
136 void Dump(std::ostream
&os
) const;
139 BXEXPORT
inline std::ostream
& operator<< (std::ostream
&os
, const RecordStateTable
&rst
) {
146 struct BXEXPORT DatabaseItem
149 unsigned int RecordCount
;
153 class BXEXPORT DatabaseDatabase
156 typedef DatabaseItem Database
;
157 typedef std::vector
<Database
> DatabaseArrayType
;
159 DatabaseArrayType Databases
;
162 template <class RecordType
, class FieldType
>
163 void ParseRec(const RecordType
&rec
, const unsigned char *end
);
165 template <class FieldType
>
166 const unsigned char* ParseField(const unsigned char *begin
,
167 const unsigned char *end
);
173 void Parse(const Data
&data
);
177 unsigned int GetTotalRecordCount() const;
179 // returns true on success, and fills target
180 bool GetDBNumber(const std::string
&name
, unsigned int &number
) const;
181 bool GetDBName(unsigned int number
, std::string
&name
) const;
183 void Dump(std::ostream
&os
) const;
186 BXEXPORT
inline std::ostream
& operator<<(std::ostream
&os
, const DatabaseDatabase
&dbdb
) {
193 std::string raw_data
;
195 const std::string::value_type
* data() const { return raw_data
.data(); }
196 std::string::size_type
size() const { return raw_data
.size(); }
197 void assign(const std::string::value_type
*s
, std::string::size_type n
)
198 { raw_data
.assign(s
, n
); }
201 struct BXEXPORT UnknownField
206 typedef std::vector
<UnknownField
> UnknownsType
;
207 BXEXPORT
std::ostream
& operator<< (std::ostream
&os
, const UnknownsType
&unknowns
);
209 // simple email type and list
210 typedef std::string EmailType
;
211 typedef std::vector
<EmailType
> EmailList
;
213 // struct, attempting to combine name + email address, for mail
214 struct BXEXPORT EmailAddress
223 /// Converts "Name <address@host.com>" into Name + Address
224 /// Will also handle just a plain address too.
225 explicit EmailAddress(const std::string
&complex_address
);
235 return Name
.size() + Email
.size();
238 BXEXPORT
std::ostream
& operator<<(std::ostream
&os
, const EmailAddress
&msga
);
240 class BXEXPORT EmailAddressList
: public std::vector
<EmailAddress
>
243 std::string
ToCommaSeparated() const;
244 void AddCommaSeparated(const std::string
&list
);
247 BXEXPORT
std::ostream
& operator<<(std::ostream
&os
, const EmailAddressList
&elist
);
249 struct BXEXPORT PostalAddress
260 std::string
GetLabel() const;
263 bool HasData() const { return Address1
.size() || Address2
.size() ||
264 Address3
.size() || City
.size() || Province
.size() ||
265 PostalCode
.size() || Country
.size(); }
267 BXEXPORT
std::ostream
& operator<<(std::ostream
&os
, const PostalAddress
&msga
);
271 int Month
; // 0 to 11
273 int Year
; // exact number, eg. 2008
275 Date() : Month(0), Day(0), Year(0) {}
276 explicit Date(const struct tm
*timep
);
278 bool HasData() const { return Month
|| Day
|| Year
; }
281 void ToTm(struct tm
*timep
) const;
282 std::string
ToYYYYMMDD() const;
283 std::string
ToBBString() const; // converts to Blackberry string
284 // format of DD/MM/YYYY
286 bool FromTm(const struct tm
*timep
);
287 bool FromBBString(const std::string
&str
);
288 bool FromYYYYMMDD(const std::string
&str
);
290 BXEXPORT
std::ostream
& operator<<(std::ostream
&os
, const Date
&date
);
292 class BXEXPORT CategoryList
: public std::vector
<std::string
>
295 /// Parses the given comma delimited category string into
296 /// this CategoryList object, appending each token to the vector.
297 /// Will clear vector beforehand.
298 void CategoryStr2List(const std::string
&str
);
300 /// Turns the current vectory into a comma delimited category
301 /// string suitable for use in Calendar, Task, and Memo
303 void CategoryList2Str(std::string
&str
) const;
305 using std::vector
<std::string
>::operator=;
310 //////////////////////////////////////////////////////////////////////////////
311 // Generic Field Handles
313 /// \addtogroup GenericFieldHandles
314 /// Generic field handle classes, used to reference and work
315 /// with record members in a flexible, indirect way.
317 /// There are two ways to access device record data. The obvious
318 /// way is to instantiate a record class, such as Contact, and
319 /// access the public data members of that class to read and
320 /// write. If you always work with the same record class, this
323 /// The other way is to have a list of pointers to members.
324 /// For example, you may wish to compare two records, without
325 /// actually caring what data is in each one. You can compare
326 /// at the record class level, with Contact one, two; and then
327 /// if( one == two ), but this will not tell you what field in
328 /// the record changed.
330 /// This last feature is what Generic Field Handles are meant to
331 /// fix. Each record class will contain a GetFieldHandles()
332 /// member function, which will return a vector of FieldHandle<>
333 /// objects, for that specific record. For example, Contact
334 /// would fill a vector with FieldHandle<Contact> objects.
335 /// Each FieldHandle<> object contains a C++ pointer-to-member,
336 /// which the FieldHandle refers to, as well as a FieldIdentity
337 /// object. The FieldIdentity object contains various identitying
338 /// information, such as the C++ variable name, an English
339 /// (or localized language) display name of the field, suitable
340 /// for user prompts, and other data more useful to the library.
342 /// The FieldHandle<> object has two member functions: Value()
345 /// Value() will call a callback function with the _value_ of
346 /// the variable that FieldHandle<> points to. For example,
347 /// if the FieldHandle<> points to a std::string record member
348 /// variable, then Value() will pass that string value in as
349 /// an argument, along with a reference to the FieldIdentity
350 /// object. Value() requires a callback object and a record
351 /// object to perform this callback.
353 /// Member() will call a callback function/functor with the
354 /// pointer-to-member pointer and the FieldIdentity object.
355 /// This allows the programmer to create a functor with multiple
356 /// record objects, perhaps two objects to compare individual
357 /// fields, and use the pointer-to-member to access the field
360 /// For now, all data and callbacks are const, meaning that it
361 /// is not possible (without const_casting) to write to the
362 /// record via the pointers-to-members. This design decision
363 /// may need to be revisited someday, depending on its usefulness.
370 /// This class holds data that identifies a given field in a record.
371 /// This is fairly constant data, referenced by the FieldHandle class.
372 /// The information in here should be enough to show the user what kind
373 /// of field this is.
375 struct BXEXPORT FieldIdentity
377 // useful public data
378 const char *Name
; // C++ name of field member variable in
380 std::string DisplayName
; // localized display name of field
382 // FIXME - should we leave localization
383 // to the application?
385 // subfield detection
386 bool HasSubfields
; // true if this field has subfields
387 const char *ParentName
; // name of field member variable that
388 // this field is a member of, or NULL
389 // if this field is a member of the
391 // For example, Contact::PostalAddress
392 // would have HasSubfields == true,
393 // and ParentName == NULL, while all
394 // its subfield strings would have
395 // HasSubfields == false and
396 // ParentName == "WorkAddress" or
398 // The application could then decide
399 // whether to process only main fields,
400 // some of which have subfields,
401 // or only individual subfields.
403 // internal field data
404 int FieldTypeCode
; // device type code for this field.
405 // if -1, then this is a conglomerate
406 // C++ field, such as
407 // Contact::PostalAddress, not a device
409 // If -1, then none of the following
411 const char *Ldif
; // matching LDIF field name, or NULL
412 const char *ObjectClass
; // matching LDIF object class, or NULL
413 bool IconvNeeded
; // if true, the device's data needs to
414 // be passed through an IConverter
416 FieldIdentity(const char *name
, const std::string
&display_name
,
418 bool iconvneeded
= false,
419 const char *ldif
= 0, const char *oclass
= 0,
420 bool has_sub
= false, const char *parent
= 0
423 , DisplayName(display_name
)
424 , HasSubfields(has_sub
)
426 , FieldTypeCode(type_code
)
428 , ObjectClass(oclass
)
429 , IconvNeeded(iconvneeded
)
437 /// This is the base class for the hierarchy of classes to define
438 /// enum record members. This is the base class, which contains the
439 /// common code for creating and defining a list of enum constants for
440 /// a given enum field. The next derived class is EnumFieldBase<RecordT>,
441 /// which defines the virtual API for talking to a given enum field
442 /// in a given record. The next derived class is EnumField<RecordT, EnumT>,
443 /// which implements the pointer-to-member and virtual API for a given
444 /// enum type in a given record class.
446 /// For example, the Bookmark record class has the following enum field:
449 /// enum BrowserIdentityType
451 /// IdentityAuto = 0,
452 /// IdentityBlackBerry,
454 /// IdentityInternetExplorer,
457 /// BrowserIdentityType BrowserIdentity;
460 /// The EnumConstants class will hold a vector of EnumConstant structs
461 /// defining each of the identity constants: Auto, BlackBerry, FireFox,
462 /// InternetExplorer, and Unknown.
464 /// The derived class EnumFieldBase<Bookmark> will define two additional
465 /// pure virtual API calls: GetValue(const Bookmark&) and
466 /// SetValue(Bookmark&, int).
468 /// Finally, the derived class EnumField<Bookmark,Bookmark::BrowserIdentityType>
469 /// will implement the virtual API, and contain a pointer-to-member to
470 /// the Bookmark::BrowserIdentity member field.
472 /// The FieldHandle<Bookmark> class will hold a pointer to
473 /// EnumFieldBase<Bookmark>, which can hold a pointer to a specific
474 /// EnumField<> object, one object for each of Bookmark's enum types,
475 /// of which there are currently 3.
477 class BXEXPORT EnumConstants
480 /// This defines one of the enum constants being defined.
481 /// For example, for an enum declaration like:
482 /// enum Mine { A, B, C }; then this struct could contain
483 /// a definition for A, B, or C, but only one at at time.
484 /// All three would be defined by the EnumConstantList.
487 const char *Name
; //< C++ name of enum constant
488 std::string DisplayName
; //< user-friendly name / meaning
489 int Value
; //< constant enum value
491 EnumConstant(const char *name
, const std::string
&display
,
494 , DisplayName(display
)
500 typedef std::vector
<EnumConstant
> EnumConstantList
;
503 EnumConstantList m_constants
;
506 virtual ~EnumConstants() {}
508 /// Adds a constant definition to the list
509 void AddConstant(const char *name
, const std::string
&display
, int val
);
511 /// Returns a vector of EnumConstant objects, describing all enum
512 /// constants valid for this enum field.
513 const EnumConstantList
& GetConstantList() const { return m_constants
; }
515 /// Returns the EnumConstant for the given value.
516 /// Throws std::logic_error if not found.
517 const EnumConstant
& GetConstant(int value
) const;
519 /// Returns the constant name (C++ name) based on the given value.
520 /// Throws std::logic_error if not found.
521 const char* GetName(int value
) const;
523 /// Returns the display name based on the given value.
524 /// Throws std::logic_error if not found.
525 const std::string
& GetDisplayName(int value
) const;
527 /// Returns true if the value matches one of the constants in the list.
528 bool IsConstantValid(int value
) const;
532 // FieldValueHandlerBase
534 /// This is a pure virtual base class, defining the various types that
535 /// record fields can be. To be able to handle all the types of data
536 /// in all records, override these virtual functions to do with the
537 /// data as you wish.
539 /// All data from the records and fields will be passed in by value.
540 /// i.e. if field is string data, the overloaded std::string handler
541 /// will be called, and a refernce to the string will be passed in.
543 /// The advantage of using this virtual class is that less code will be
544 /// generated by templates. The disadvantage is that this is less flexible.
545 /// You will only get called for one field and record at a time.
546 /// So you can't do comparisons this way.
548 class BXEXPORT FieldValueHandlerBase
551 virtual ~FieldValueHandlerBase() {}
553 /// For type std::string
554 virtual void operator()(const std::string
&v
,
555 const FieldIdentity
&id
) const = 0;
556 /// For type EmailAddressList
557 virtual void operator()(const EmailAddressList
&v
,
558 const FieldIdentity
&id
) const = 0;
560 virtual void operator()(const time_t &v
,
561 const FieldIdentity
&id
) const = 0;
563 virtual void operator()(const uint8_t &v
,
564 const FieldIdentity
&id
) const = 0;
565 /// For type uint16_t
566 virtual void operator()(const uint16_t &v
,
567 const FieldIdentity
&id
) const = 0;
568 /// For type uint32_t
569 virtual void operator()(const uint32_t &v
,
570 const FieldIdentity
&id
) const = 0;
571 /// For type uint64_t
572 virtual void operator()(const uint64_t &v
,
573 const FieldIdentity
&id
) const = 0;
575 virtual void operator()(const bool &v
,
576 const FieldIdentity
&id
) const = 0;
578 virtual void operator()(const int32_t &v
,
579 const FieldIdentity
&id
) const = 0;
580 /// For type EmailList
581 virtual void operator()(const EmailList
&v
,
582 const FieldIdentity
&id
) const = 0;
584 virtual void operator()(const Date
&v
,
585 const FieldIdentity
&id
) const = 0;
586 /// For type CategoryList
587 virtual void operator()(const CategoryList
&v
,
588 const FieldIdentity
&id
) const = 0;
589 /// For type PostalAddress
590 virtual void operator()(const PostalAddress
&v
,
591 const FieldIdentity
&id
) const = 0;
592 /// For type UnknownsType
593 virtual void operator()(const UnknownsType
&v
,
594 const FieldIdentity
&id
) const = 0;
598 /// EnumFieldBase<RecordT>
600 template <class RecordT
>
601 class EnumFieldBase
: public EnumConstants
604 /// Return value of enum in rec
605 virtual int GetValue(const RecordT
&rec
) const = 0;
606 /// Set value of enum in rec
607 /// Throws std::logic_error if value is out of range
608 virtual void SetValue(RecordT
&rec
, int value
) = 0;
612 /// EnumField<RecordT, EnumT>
614 template <class RecordT
, class EnumT
>
615 class EnumField
: public EnumFieldBase
<RecordT
>
617 EnumT
RecordT::* m_mp
;
620 explicit EnumField(EnumT
RecordT::* mp
)
625 virtual int GetValue(const RecordT
&rec
) const
630 virtual void SetValue(RecordT
&rec
, int value
)
632 if( !this->IsConstantValid(value
) )
633 throw std::logic_error("Bad enum value in EnumField");
634 rec
.*m_mp
= (EnumT
) value
;
639 // FieldHandle<RecordT>
641 /// This is a template class that handles pointers to members of multiple
642 /// types of data and multiple types of records.
644 /// This class contains a union of all known data pointers in all records.
645 /// Therefore this class can hold a pointer to member of any record class.
647 /// To do something with the field that this FieldHandle<> class refers to,
648 /// call either Value() or Member() with appropriate callback functors.
649 /// Value will pass a reference to the field. You can use an object
650 /// derived from FieldValueHandlerBase here. Member() will pass a pointer
651 /// to member. Your functor will need to contain the record data in order
652 /// to access its data via the pointer to member.
654 /// The template functor callback that you pass into member must be
658 /// template <class RecordT>
663 /// void operator()(typename FieldHandle<RecordT>::PostalPointer pp,
664 /// const FieldIdentity &id) const
666 /// PostalAddress pa = m_rec.*(pp.m_PostalAddress);
667 /// std::string val = pa.*(pp.m_PostalField);
671 /// template <class TypeT>
672 /// void operator()(TypeT RecordT::* mp,
673 /// const FieldIdentity &id) const
675 /// TypeT val = m_rec.*mp;
681 /// You don't have to use a TypeT template, but if you don't, then you must
682 /// support all field types that the record class you're processing uses.
685 template <class RecordT
>
689 // Need to use this in the union, so no constructor allowed
692 PostalAddress
RecordT::* m_PostalAddress
;
693 std::string
PostalAddress::* m_PostalField
;
696 // So use a factory function
697 static PostalPointer
MakePostalPointer(PostalAddress
RecordT::* p1
,
698 std::string
PostalAddress::* p2
)
701 pp
.m_PostalAddress
= p1
;
702 pp
.m_PostalField
= p2
;
709 std::string
RecordT::* m_string
; // index 0
710 EmailAddressList
RecordT::* m_EmailAddressList
; // 1
711 time_t RecordT::* m_time
; // 2
712 PostalPointer m_postal
; // 3
713 uint8_t RecordT::* m_uint8
; // 4
714 uint32_t RecordT::* m_uint32
; // 5
715 EmailList
RecordT::* m_EmailList
; // 6
716 Date
RecordT::* m_Date
; // 7
717 CategoryList
RecordT::* m_CategoryList
; // 8
718 // GroupLinksType RecordT::* m_GroupLinksType; // 9
719 UnknownsType
RecordT::* m_UnknownsType
; // 10
720 bool RecordT::* m_bool
; // 11
721 uint64_t RecordT::* m_uint64
; // 12
722 uint16_t RecordT::* m_uint16
; // 13
723 PostalAddress
RecordT::* m_PostalAddress
; // 14
724 // used by non-union m_enum below: // 15
725 int32_t RecordT::* m_int32
; // 16
729 PointerUnion m_union
;
730 EnumFieldBase
<RecordT
> *m_enum
; // never freed, since this is a
731 // static list, existing to end of
738 FieldHandle(std::string
RecordT::* mp
, const FieldIdentity
&id
)
743 m_union
.m_string
= mp
;
747 FieldHandle(EmailAddressList
RecordT::* mp
, const FieldIdentity
&id
)
752 m_union
.m_EmailAddressList
= mp
;
756 FieldHandle(time_t RecordT::* mp
, const FieldIdentity
&id
)
765 FieldHandle(const PostalPointer
&pp
, const FieldIdentity
&id
)
770 m_union
.m_postal
= pp
;
774 FieldHandle(uint8_t RecordT::* mp
, const FieldIdentity
&id
)
779 m_union
.m_uint8
= mp
;
783 FieldHandle(uint32_t RecordT::* mp
, const FieldIdentity
&id
)
788 m_union
.m_uint32
= mp
;
792 FieldHandle(EmailList
RecordT::* mp
, const FieldIdentity
&id
)
797 m_union
.m_EmailList
= mp
;
801 FieldHandle(Date
RecordT::* mp
, const FieldIdentity
&id
)
810 FieldHandle(CategoryList
RecordT::* mp
, const FieldIdentity
&id
)
815 m_union
.m_CategoryList
= mp
;
819 // FieldHandle(GroupLinksType RecordT::* mp, const FieldIdentity &id)
824 // m_union.m_GroupLinksType = mp;
828 FieldHandle(UnknownsType
RecordT::* mp
, const FieldIdentity
&id
)
833 m_union
.m_UnknownsType
= mp
;
837 FieldHandle(bool RecordT::* mp
, const FieldIdentity
&id
)
846 FieldHandle(uint64_t RecordT::* mp
, const FieldIdentity
&id
)
851 m_union
.m_uint64
= mp
;
855 FieldHandle(uint16_t RecordT::* mp
, const FieldIdentity
&id
)
860 m_union
.m_uint16
= mp
;
864 FieldHandle(PostalAddress
RecordT::* mp
, const FieldIdentity
&id
)
869 m_union
.m_PostalAddress
= mp
;
873 FieldHandle(EnumFieldBase
<RecordT
> *enum_
, const FieldIdentity
&id
)
881 FieldHandle(int32_t RecordT::* mp
, const FieldIdentity
&id
)
886 m_union
.m_int32
= mp
;
889 /// Extracts FieldIdentity object from FieldHandle<>
890 const FieldIdentity
& GetIdentity() const { return m_id
; }
892 /// Calls the matching virtual function in FieldValueHandlerBase,
893 /// passing in the value of the field that this FieldHandle<>
894 /// refers to, and a referenct to the FieldIdentity object.
895 /// Caller must pass in a RecordT object as well.
896 void Value(const FieldValueHandlerBase
&vh
, const RecordT
&rec
) const
898 switch( m_type_index
)
901 vh(rec
.*(m_union
.m_string
), m_id
);
904 vh(rec
.*(m_union
.m_EmailAddressList
), m_id
);
907 vh(rec
.*(m_union
.m_time
), m_id
);
910 vh(rec
.*(m_union
.m_postal
.m_PostalAddress
).*(m_union
.m_postal
.m_PostalField
), m_id
);
913 vh(rec
.*(m_union
.m_uint8
), m_id
);
916 vh(rec
.*(m_union
.m_uint32
), m_id
);
919 vh(rec
.*(m_union
.m_EmailList
), m_id
);
922 vh(rec
.*(m_union
.m_Date
), m_id
);
925 vh(rec
.*(m_union
.m_CategoryList
), m_id
);
928 // vh(rec.*(m_union.m_GroupLinksType), m_id);
931 vh(rec
.*(m_union
.m_UnknownsType
), m_id
);
934 vh(rec
.*(m_union
.m_bool
), m_id
);
937 vh(rec
.*(m_union
.m_uint64
), m_id
);
940 vh(rec
.*(m_union
.m_uint16
), m_id
);
943 vh(rec
.*(m_union
.m_PostalAddress
), m_id
);
946 vh(m_enum
->GetValue(rec
), m_id
);
949 vh(rec
.*(m_union
.m_int32
), m_id
);
952 throw std::logic_error("Unknown field handle type index");
956 /// Calls the callback functor with two arguments: the pointer to
957 /// member that this FieldHandle<> contains, and the FieldIdentity
958 /// object. It is assumed that the functor will either contain
959 /// or know where to find one or more records of type RecordT.
960 template <class CallbackT
>
961 void Member(const CallbackT
&func
) const
963 switch( m_type_index
)
966 func(m_union
.m_string
, m_id
);
969 func(m_union
.m_EmailAddressList
, m_id
);
972 func(m_union
.m_time
, m_id
);
975 func(m_union
.m_postal
, m_id
);
978 func(m_union
.m_uint8
, m_id
);
981 func(m_union
.m_uint32
, m_id
);
984 func(m_union
.m_EmailList
, m_id
);
987 func(m_union
.m_Date
, m_id
);
990 func(m_union
.m_CategoryList
, m_id
);
993 // func(m_union.m_GroupLinksType, m_id);
996 func(m_union
.m_UnknownsType
, m_id
);
999 func(m_union
.m_bool
, m_id
);
1002 func(m_union
.m_uint64
, m_id
);
1005 func(m_union
.m_uint16
, m_id
);
1008 func(m_union
.m_PostalAddress
, m_id
);
1014 func(m_union
.m_int32
, m_id
);
1017 throw std::logic_error("Unknown field handle type index");
1022 /// Factory function to create a FieldHandle<> object.
1023 template <class RecordT
, class TypeT
>
1024 FieldHandle
<RecordT
> MakeFieldHandle(TypeT
RecordT::* tp
,
1025 const FieldIdentity
&id
)
1027 return FieldHandle
<RecordT
>(tp
, id
);
1030 /// Calls FileHandle<>::Member() for each defined field for a given record type.
1031 /// Takes a vector of FileHandle<> objects, and calls Member(func) for each one.
1032 template <class HandlesT
, class CallbackT
>
1033 void ForEachField(const HandlesT
&handles
, const CallbackT
&func
)
1035 typename
HandlesT::const_iterator
1036 b
= handles
.begin(),
1038 for( ; b
!= e
; ++b
) {
1043 /// Calls FileHandle<>::Value() for each defined field for a given record.
1044 /// Takes a RecordT object and calls Value(vh, rec) for each FileHandle<>
1045 /// object in the record's FileHandles set.
1046 template <class RecordT
>
1047 void ForEachFieldValue(const RecordT
&rec
, const FieldValueHandlerBase
&vh
)
1049 typename
std::vector
<FieldHandle
<RecordT
> >::const_iterator
1050 b
= RecordT::GetFieldHandles().begin(),
1051 e
= RecordT::GetFieldHandles().end();
1052 for( ; b
!= e
; ++b
) {
1058 // FieldHandle setup macros
1060 // #undef and #define the following macros to override these macros for you:
1062 // CONTAINER_OBJECT_NAME - the new FieldHandles will be .push_back()'d into
1064 // RECORD_CLASS_NAME - the name of the record class you are defining,
1065 // i.e. Barry::Contact, or Barry::Calendar
1068 // plain field, no connection to device field
1069 #define FHP(name, display) \
1070 CONTAINER_OBJECT_NAME.push_back( \
1071 FieldHandle<RECORD_CLASS_NAME>(&RECORD_CLASS_NAME::name, \
1072 FieldIdentity(#name, display)))
1073 // record field with direct connection to device field, no LDIF data
1074 #define FHD(name, display, type_code, iconv) \
1075 CONTAINER_OBJECT_NAME.push_back( \
1076 FieldHandle<RECORD_CLASS_NAME>(&RECORD_CLASS_NAME::name, \
1077 FieldIdentity(#name, display, type_code, iconv, \
1079 // record field with direct connection to device field, with LDIF data
1080 #define FHL(name, display, type_code, iconv, ldif, oclass) \
1081 CONTAINER_OBJECT_NAME.push_back( \
1082 FieldHandle<RECORD_CLASS_NAME>(&RECORD_CLASS_NAME::name, \
1083 FieldIdentity(#name, display, type_code, iconv, \
1085 // a subfield of a conglomerate field, with direct connection to device field,
1087 #define FHS(name, subname, display, type, iconv, ldif, oclass) \
1088 CONTAINER_OBJECT_NAME.push_back( \
1089 FieldHandle<RECORD_CLASS_NAME>( \
1090 FieldHandle<RECORD_CLASS_NAME>::MakePostalPointer( \
1091 &RECORD_CLASS_NAME::name, \
1092 &PostalAddress::subname), \
1093 FieldIdentity(#name "::" #subname, display, \
1094 type, iconv, ldif, oclass, \
1096 // record conglomerate field, which has subfields
1097 #define FHC(name, display) \
1098 CONTAINER_OBJECT_NAME.push_back( \
1099 FieldHandle<RECORD_CLASS_NAME>(&RECORD_CLASS_NAME::name, \
1100 FieldIdentity(#name, display, \
1101 -1, false, 0, 0, true, 0)))
1102 // create a new EnumField<> and add it to the list... use the new_var_name
1103 // to add constants with FHE_CONST below
1104 #define FHE(new_var_name, record_field_type, record_field_name, display) \
1105 EnumField<RECORD_CLASS_NAME, RECORD_CLASS_NAME::record_field_type> \
1106 *new_var_name = new \
1107 EnumField<RECORD_CLASS_NAME, RECORD_CLASS_NAME::record_field_type> \
1108 (&RECORD_CLASS_NAME::record_field_name); \
1109 CONTAINER_OBJECT_NAME.push_back( \
1110 FieldHandle<RECORD_CLASS_NAME>(new_var_name, \
1111 FieldIdentity(#record_field_name, display)))
1112 // add constant to enum created above
1113 #define FHE_CONST(var, name, display) \
1114 var->AddConstant(#name, display, RECORD_CLASS_NAME::name)
1118 } // namespace Barry
1121 /// \addtogroup RecordParserClasses
1122 /// Parser and data storage classes. These classes take a
1123 /// Database Database record and convert them into C++ objects.
1124 /// Each of these classes are safe to be used in standard
1125 /// containers, and are meant to be used in conjunction with the
1126 /// RecordParser<> template when calling Controller::LoadDatabase().
1130 #ifndef __BARRY_LIBRARY_BUILD__
1131 // Include all parser classes, to make it easy for the application to use.
1132 #include "r_calendar.h"
1133 #include "r_calllog.h"
1134 #include "r_bookmark.h"
1135 #include "r_contact.h"
1136 #include "r_cstore.h"
1138 #include "r_message.h"
1139 #include "r_servicebook.h"
1141 #include "r_pin_message.h"
1142 #include "r_saved_message.h"
1144 #include "r_folder.h"
1145 #include "r_timezone.h"
1146 #include "r_hhagent.h"