Here is a patch to add PIN Message and add some additional fields to Message.
Note that I had to make a change to FieldLinks<T>. It had originally included a direct reference to a Message::Address which wouldn't allow a PINMessage::Address (or others for future adds). I created an Address object in record.h and made the necessary changes in r_message and r_pin_message and record-internal.h. Saved Email Messages is coming next, along with a rough cut at the Message header itself, which will provide the recieved and sent dates, the flags having to do with opened, not read, truncated, saved, etc. Chris: I made a quick hack to src/Makefile.am to get these in but you might want to add them differently. -edge
Index: src/r_message.h
===================================================================
RCS file: /cvsroot/barry/barry/src/r_message.h,v
retrieving revision 1.1
diff -u -r1.1 r_message.h
--- src/r_message.h 25 May 2007 06:35:34 -0000 1.1
+++ src/r_message.h 1 Jun 2007 10:37:20 -0000
@@ -42,18 +42,16 @@
class Message
{
public:
- struct Address
- {
- std::string Name;
- std::string Email;
- };
-
Address From;
Address To;
Address Cc;
+ Address Bcc;
+ Address Sender;
+ Address ReplyTo;
std::string Subject;
std::string Body;
+ std::string Attachment;
std::vector<UnknownField> Unknowns;
public:
@@ -90,7 +88,7 @@
return os;
}
-std::ostream& operator<<(std::ostream &os, const Message::Address &msga);
+std::ostream& operator<<(std::ostream &os, const Address &msga);
/// @}
Index: src/record-internal.h
===================================================================
RCS file: /cvsroot/barry/barry/src/record-internal.h,v
retrieving revision 1.2
diff -u -r1.2 record-internal.h
--- src/record-internal.h 25 May 2007 20:34:05 -0000 1.2
+++ src/record-internal.h 1 Jun 2007 10:37:20 -0000
@@ -68,7 +68,7 @@
char *ldif;
char *objectClass;
std::string RecordT::* strMember; // FIXME - find a more general
- Message::Address RecordT::* addrMember; // way to do this...
+ Address RecordT::* addrMember; // way to do this...
time_t RecordT::* timeMember;
};
Index: src/r_message.cc
===================================================================
RCS file: /cvsroot/barry/barry/src/r_message.cc,v
retrieving revision 1.1
diff -u -r1.1 r_message.cc
--- src/r_message.cc 25 May 2007 06:35:34 -0000 1.1
+++ src/r_message.cc 1 Jun 2007 10:37:20 -0000
@@ -40,7 +40,7 @@
namespace Barry {
-std::ostream& operator<<(std::ostream &os, const Message::Address &msga) {
+std::ostream& operator<<(std::ostream &os, const Address &msga) {
os << msga.Name.c_str() << " <" << msga.Email.c_str() << ">";
return os;
}
@@ -51,17 +51,27 @@
// Email / message field codes
#define MFC_TO 0x01 // can occur multiple times
+#define MFC_CC 0x02 // ditto
+#define MFC_BCC 0x03 // ditto
+#define MFC_SENDER 0x04
#define MFC_FROM 0x05
+#define MFC_REPLY_TO 0x06
#define MFC_SUBJECT 0x0b
#define MFC_BODY 0x0c
+#define MFC_ATTACHMENT 0x16
#define MFC_END 0xffff
FieldLink<Message> MessageFieldLinks[] = {
- { MFC_TO, "To", 0, 0, 0, &Message::To, 0 },
- { MFC_FROM, "From", 0, 0, 0, &Message::From, 0 },
- { MFC_SUBJECT, "Subject", 0, 0, &Message::Subject, 0, 0 },
- { MFC_BODY, "Body", 0, 0, &Message::Body, 0, 0 },
- { MFC_END, "End of List",0, 0, 0, 0, 0 }
+ { MFC_TO, "To", 0, 0, 0, &Message::To, 0 },
+ { MFC_CC, "Cc", 0, 0, 0, &Message::Cc, 0 },
+ { MFC_BCC, "Bcc", 0, 0, 0, &Message::Bcc, 0 },
+ { MFC_SENDER, "Sender", 0, 0, 0, &Message::Sender, 0 },
+ { MFC_FROM, "From", 0, 0, 0, &Message::From, 0 },
+ { MFC_REPLY_TO, "ReplyTo", 0, 0, 0, &Message::ReplyTo, 0 },
+ { MFC_SUBJECT, "Subject", 0, 0, &Message::Subject, 0, 0 },
+ { MFC_BODY, "Body", 0, 0, &Message::Body, 0, 0 },
+ { MFC_ATTACHMENT, "Attachment", 0, 0, &Message::Attachment, 0, 0 },
+ { MFC_END, "End of List", 0, 0, 0, 0, 0 }
};
Message::Message()
@@ -109,10 +119,17 @@
// assign second string, using first size as starting point
a.Email = dual.c_str() + a.Name.size() + 1;
+ return begin;
}
}
}
+ // if still not handled, add to the Unknowns list
+ UnknownField uf;
+ uf.type = field->type;
+ uf.data.assign((const char*)field->u.raw, btohs(field->size));
+ Unknowns.push_back(uf);
+
return begin;
}
@@ -164,8 +181,17 @@
To.Email.clear();
Cc.Name.clear();
Cc.Email.clear();
+ Bcc.Email.clear();
+ Bcc.Name.clear();
+ Sender.Name.clear();
+ Sender.Email.clear();
+ ReplyTo.Name.clear();
+ ReplyTo.Email.clear();
Subject.clear();
Body.clear();
+ Attachment.clear();
+
+ Unknowns.clear();
}
// dump message in mbox format
@@ -182,6 +208,12 @@
os << "To: " << To << "\n";
if( Cc.Email.size() )
os << "Cc: " << Cc << "\n";
+ if( Bcc.Email.size() )
+ os << "Bcc: " << Bcc << "\n";
+ if( Sender.Email.size() )
+ os << "Sender: " << Sender << "\n";
+ if( ReplyTo.Email.size())
+ os << "Reply To: " << ReplyTo << "\n";
if( Subject.size() )
os << "Subject: " << Subject << "\n";
os << "\n";
@@ -194,6 +226,11 @@
else
os << *i;
}
+ os << "\n";
+ if( Attachment.size() )
+ os << "Attachments: " << Attachment << "\n";
+
+ os << Unknowns;
os << "\n\n";
}
Index: src/s11n-boost.h
===================================================================
RCS file: /cvsroot/barry/barry/src/s11n-boost.h,v
retrieving revision 1.6
diff -u -r1.6 s11n-boost.h
--- src/s11n-boost.h 27 May 2007 17:19:25 -0000 1.6
+++ src/s11n-boost.h 1 Jun 2007 10:37:21 -0000
@@ -113,7 +113,7 @@
}
template <class ArchiveT>
-void serialize(ArchiveT &ar, Barry::Message::Address &a, const unsigned int ver)
+void serialize(ArchiveT &ar, Barry::Address &a, const unsigned int ver)
{
ar & make_nvp("Name", a.Name);
ar & make_nvp("Email", a.Email);
@@ -125,8 +125,11 @@
ar & make_nvp("From", m.From);
ar & make_nvp("To", m.To);
ar & make_nvp("Cc", m.Cc);
+ ar & make_nvp("Sender", m.Sender);
+ ar & make_nvp("ReplyTo", m.ReplyTo);
ar & make_nvp("Subject", m.Subject);
ar & make_nvp("Body", m.Body);
+ ar & make_nvp("Attachment", m.Attachment);
if( ver < BARRY_POD_MAP_VERSION ) {
ar & make_nvp("Unknowns", m.Unknowns);
@@ -216,6 +219,21 @@
}
}
+template<class ArchiveT>
+void serialize(ArchiveT &ar, Barry::PINMessage &p, const unsigned int ver)
+{
+ ar & make_nvp("From", p.From);
+ ar & make_nvp("To", p.To);
+ ar & make_nvp("Cc", p.Cc);
+ ar & make_nvp("Bcc", p.Bcc);
+ ar & make_nvp("Subject", p.Subject);
+ ar & make_nvp("Body", p.Body);
+
+ if(ver < BARRY_POD_MAP_VERSION) {
+ ar & make_nvp("Unknowns", p.Unknowns);
+ }
+}
+
}} // namespace boost::serialization
#endif
Index: src/record.h
===================================================================
RCS file: /cvsroot/barry/barry/src/record.h,v
retrieving revision 1.23
diff -u -r1.23 record.h
--- src/record.h 25 May 2007 21:29:00 -0000 1.23
+++ src/record.h 1 Jun 2007 10:37:20 -0000
@@ -174,6 +174,11 @@
};
std::ostream& operator<< (std::ostream &os, const std::vector<UnknownField> &unknowns);
+typedef struct Address
+{
+ std::string Name;
+ std::string Email;
+};
/// \addtogroup RecordParserClasses
/// Parser and data storage classes. These classes take a
@@ -193,6 +198,7 @@
#include "r_message.h"
#include "r_servicebook.h"
#include "r_task.h"
+#include "r_pin_message.h"
#endif
Index: src/Makefile.am
===================================================================
RCS file: /cvsroot/barry/barry/src/Makefile.am,v
retrieving revision 1.15
diff -u -r1.15 Makefile.am
--- src/Makefile.am 25 May 2007 21:29:00 -0000 1.15
+++ src/Makefile.am 1 Jun 2007 10:37:20 -0000
@@ -68,6 +68,7 @@
r_message.h \
r_servicebook.h \
r_task.h \
+ r_pin_message.h \
socket.h \
time.h \
usbwrap.h \
@@ -93,6 +94,7 @@
r_message.cc \
r_servicebook.cc \
r_task.cc \
+ r_pin_message.cc
packet.cc packet.h \
controller.cc \
version.cc \
Index: tools/btool.cc
===================================================================
RCS file: /cvsroot/barry/barry/tools/btool.cc,v
retrieving revision 1.16
diff -u -r1.16 btool.cc
--- tools/btool.cc 27 May 2007 17:19:25 -0000 1.16
+++ tools/btool.cc 1 Jun 2007 10:37:21 -0000
@@ -229,6 +229,11 @@
new RecordParser<Task, Store<Task> > (
new Store<Task>(filename, false )));
}
+ else if( name == "PIN Messages" ) {
+ return auto_ptr<Parser>(
+ new RecordParser<PINMessage, Store<PINMessage> > (
+ new Store<PINMessage>(filename, false )));
+ }
else {
// unknown database, use null parser
return auto_ptr<Parser>( new DataDumpParser );
Index: src/r_pin_message.cc
===================================================================
RCS file: src/r_pin_message.cc
diff -N src/r_pin_message.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/r_pin_message.cc 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,240 @@
+///
+/// \file r_pin_message.cc
+/// Blackberry database record parser class for pin message records.
+///
+
+/*
+ Copyright (C) 2005-2007, Net Direct Inc. (http://www.netdirect.ca/)
+ Copyright (C) 2007, Brian Edginton ([EMAIL PROTECTED])
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the GNU General Public License in the COPYING file at the
+ root directory of this project for more details.
+*/
+
+#include "r_pin_message.h"
+#include "record-internal.h"
+#include "protocol.h"
+#include "protostructs.h"
+#include "data.h"
+#include "time.h"
+#include "error.h"
+#include "endian.h"
+#include <ostream>
+#include <iomanip>
+#include <time.h>
+#include <stdexcept>
+
+#define __DEBUG_MODE__
+#include "debug.h"
+
+using namespace std;
+using namespace Barry::Protocol;
+
+namespace Barry {
+
+//std::ostream& operator<<(std::ostream &os, const Address &msgp) {
+// os << msgp.Name.c_str() << " <" << msgp.Email.c_str() << ">";
+// return os;
+//}
+
+///////////////////////////////////////////////////////////////////////////////
+// PINMessage class
+
+
+// PIN message field codes
+#define PNMFC_TO 0x01 // can occur multiple times
+#define PNMFC_CC 0x02 // ditto
+#define PNMFC_BCC 0x03 // ditto
+#define PNMFC_FROM 0x05
+#define PNMFC_SUBJECT 0x0b
+#define PNMFC_BODY 0x0c
+#define PNMFC_RECORDID 0x4b // Internal Message ID, mimics header RecNumber
+#define PNMFC_END 0xffff
+
+FieldLink<PINMessage> PINMessageFieldLinks[] = {
+ { PNMFC_TO, "To", 0, 0, 0, &PINMessage::To, 0 },
+ { PNMFC_CC, "Cc", 0, 0, 0, &PINMessage::Cc, 0 },
+ { PNMFC_BCC, "Bcc", 0, 0, 0, &PINMessage::Bcc, 0 },
+ { PNMFC_FROM, "From", 0, 0, 0, &PINMessage::From, 0 },
+ { PNMFC_SUBJECT "Subject", 0, 0, &PINMessage::Subject, 0, 0 },
+ { PNMFC_BODY, "Body", 0, 0, &PINMessage::Body, 0, 0 },
+ { PNMFC_END, "End of List", 0, 0, 0, 0, 0 }
+};
+
+PINMessage::PINMessage()
+{
+}
+
+PINMessage::~PINMessage()
+{
+}
+
+const unsigned char* PINMessage::ParseField(const unsigned char *begin,
+ const unsigned char *end)
+{
+ const CommonField *field = (const CommonField *) begin;
+
+ // advance and check size
+ begin += COMMON_FIELD_HEADER_SIZE + btohs(field->size);
+ if( begin > end ) // if begin==end, we are ok
+ return begin;
+
+ if( !btohs(field->size) ) // if field has no size, something's up
+ return begin;
+
+ // cycle through the type table
+ for( FieldLink<PINMessage> *b = PINMessageFieldLinks;
+ b->type != PNMFC_END;
+ b++ )
+ {
+ if( b->type == field->type ) {
+ if( b->strMember ) {
+ // parse regular string
+ std::string &s = this->*(b->strMember);
+ s.assign((const char *)field->u.raw, btohs(field->size)-1);
+ return begin; // done!
+ }
+ else if( b->addrMember ) {
+ // parse email address
+ // get dual name+addr string first
+ const char *fa = (const char*)field->u.addr.addr;
+ std::string dual(fa, btohs(field->size) - sizeof(field->u.addr.unknown));
+
+ // assign first string, using null terminator...letting std::string add it for us if it doesn't exist
+ Address &a = this->*(b->addrMember);
+ a.Name = dual.c_str();
+
+ // assign second string, using first size as starting point
+ a.Email = dual.c_str() + a.Name.size() + 1;
+ return begin;
+ }
+ }
+ }
+ // handle special cases
+ switch( field->type )
+ {
+ case PNMFC_RECORDID:
+ MessageRecordId = field->u.min1900; // not really time, but we need easy access to an int
+ return begin;
+ }
+ // if still not handled, add to the Unknowns list
+ UnknownField uf;
+ uf.type = field->type;
+ uf.data.assign((const char*)field->u.raw, btohs(field->size));
+ Unknowns.push_back(uf);
+
+ return begin;
+}
+
+uint8_t PINMessage::GetRecType() const
+{
+ throw std::logic_error("PINMessage::GetRecType() called, and not supported by the USB protocol. Should never get called.");
+}
+
+// empty API, not required by protocol
+uint32_t PINMessage::GetUniqueId() const
+{
+ throw std::logic_error("PINMessage::GetUniqueId() called, and not supported by the USB protocol. Should never get called.");
+}
+
+// empty API, not required by protocol
+void PINMessage::SetIds(uint8_t Type, uint32_t Id)
+{
+ // accept it without complaining, just do nothing
+}
+
+void PINMessage::ParseHeader(const Data &data, size_t &offset)
+{
+ // we skip the "header" since we don't know what to do with it yet
+ offset += MESSAGE_RECORD_HEADER_SIZE;
+}
+
+void PINMessage::ParseFields(const Data &data, size_t &offset)
+{
+ const unsigned char *finish = ParseCommonFields(*this,
+ data.GetData() + offset, data.GetData() + data.GetSize());
+ offset += finish - (data.GetData() + offset);
+}
+
+void PINMessage::BuildHeader(Data &data, size_t &offset) const
+{
+ throw std::logic_error("PINMessage::BuildHeader not yet implemented");
+}
+
+void PINMessage::BuildFields(Data &data, size_t &offset) const
+{
+ throw std::logic_error("PINMessage::BuildFields not yet implemented");
+}
+
+void PINMessage::Clear()
+{
+
+ From.Name.clear();
+ From.Email.clear();
+
+ To.Name.clear();
+ To.Email.clear();
+
+ Cc.Name.clear();
+ Cc.Email.clear();
+
+ Bcc.Name.clear();
+ Bcc.Email.clear();
+
+ Subject.clear();
+ Body.clear();
+ MessageRecordId = 0;
+
+ Unknowns.clear();
+}
+
+// dump message in mbox format
+void PINMessage::Dump(std::ostream &os) const
+{
+ os << "Record ID (" << MessageRecordId << ")\n";
+ if( From.Name.size()) {
+ os << " From: " << From.Name << " <" << From.Email << ">\n";
+ }
+ if( To.Name.size()) {
+ os << " To: " << To.Name << " <" << To.Email << ">\n";
+ }
+ if( Cc.Name.size()) {
+ os << " Cc: " << Cc.Name << " <" << Cc.Email << ">\n";
+ }
+ if( Bcc.Name.size()) {
+ os << " Bcc: " << Bcc.Name << " <" << Bcc.Email << ">\n";
+ }
+
+ if( Subject.size() )
+ os << " Subject: " << Subject << "\n";
+ else
+ os << " Subject: <>\n";
+ os << "\n";
+
+ for( std::string::const_iterator i = Body.begin();
+ i != Body.end() && *i;
+ i++)
+ {
+ if( *i == '\r' )
+ os << '\n';
+ else
+ os << *i;
+ }
+ os << "\n";
+
+ os << Unknowns;
+ os << "\n\n";
+}
+
+
+} // namespace Barry
+
Index: src/r_pin_message.h
===================================================================
RCS file: src/r_pin_message.h
diff -N src/r_pin_message.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/r_pin_message.h 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,99 @@
+///
+/// \file r_pin_message.h
+/// Blackberry database record parser class for pin message records.
+///
+
+/*
+ Copyright (C) 2005-2007, Net Direct Inc. (http://www.netdirect.ca/)
+ Copyright (C) 2007, Brian Edginton ([EMAIL PROTECTED])
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the GNU General Public License in the COPYING file at the
+ root directory of this project for more details.
+*/
+
+#ifndef __BARRY_RECORD_PIN_MESSAGE_H__
+#define __BARRY_RECORD_PIN_MESSAGE_H__
+
+#include "record.h"
+#include <iosfwd>
+#include <string>
+#include <vector>
+#include <map>
+#include <stdint.h>
+
+namespace Barry {
+
+//
+// NOTE: All classes here must be container-safe! Perhaps add sorting
+// operators in the future.
+//
+
+/// \addtogroup RecordParserClasses
+/// @{
+
+class PINMessage
+{
+public:
+
+ Address From;
+ Address To;
+ Address Cc;
+ Address Bcc;
+ std::string Subject;
+ std::string Body;
+ uint32_t MessageRecordId;
+ std::vector<UnknownField> Unknowns;
+
+public:
+ const unsigned char* ParseField(const unsigned char *begin,
+ const unsigned char *end);
+
+public:
+ PINMessage();
+ ~PINMessage();
+
+ // Parser / Builder API (see parser.h / builder.h)
+ uint8_t GetRecType() const;
+ uint32_t GetUniqueId() const; // empty API, not required by protocol
+ void SetIds(uint8_t Type, uint32_t Id); // empty API, not required by protocol
+ void ParseHeader(const Data &data, size_t &offset);
+ void ParseFields(const Data &data, size_t &offset);
+ void BuildHeader(Data &data, size_t &offset) const;
+ void BuildFields(Data &data, size_t &offset) const;
+
+ void Clear();
+
+ void Dump(std::ostream &os) const;
+
+ // sorting
+ bool operator<(const PINMessage &other) const { return Subject < other.Subject; }
+
+ // database name
+ static const char * GetDBName() { return "PIN Messages"; }
+ static uint8_t GetDefaultRecType() { return 0; }
+};
+
+inline std::ostream& operator<<(std::ostream &os, const PINMessage &msg) {
+ msg.Dump(os);
+ return os;
+}
+
+std::ostream& operator<<(std::ostream &os, const Address &msga);
+
+
+/// @}
+
+} // namespace Barry
+
+#endif // __BARRY_RECORD_PIN_MESSAGE_H__
+
+
pgpnDmntKAVHS.pgp
Description: PGP signature
------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/
_______________________________________________ Barry-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/barry-devel
