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__
+
+

Attachment: 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
Barry-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/barry-devel

Reply via email to