2 /// \file r_pin_message.cc
3 /// Blackberry database record parser class for pin message records.
7 Copyright (C) 2005-2007, Net Direct Inc. (http://www.netdirect.ca/)
8 Copyright (C) 2007, Brian Edginton (edge@edginton.net)
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 #include "r_pin_message.h"
24 #include "record-internal.h"
26 #include "protostructs.h"
36 #define __DEBUG_MODE__
40 using namespace Barry::Protocol
;
44 //std::ostream& operator<<(std::ostream &os, const Address &msgp) {
45 // os << msgp.Name.c_str() << " <" << msgp.Email.c_str() << ">";
49 ///////////////////////////////////////////////////////////////////////////////
53 // PIN message field codes
54 #define PNMFC_TO 0x01 // can occur multiple times
55 #define PNMFC_CC 0x02 // ditto
56 #define PNMFC_BCC 0x03 // ditto
57 #define PNMFC_FROM 0x05
58 #define PNMFC_SUBJECT 0x0b
59 #define PNMFC_BODY 0x0c
60 #define PNMFC_RECORDID 0x4b // Internal Message ID, mimics header RecNumber
61 #define PNMFC_END 0xffff
63 FieldLink
<PINMessage
> PINMessageFieldLinks
[] = {
64 { PNMFC_TO
, "To", 0, 0, 0, &PINMessage::To
, 0 },
65 { PNMFC_CC
, "Cc", 0, 0, 0, &PINMessage::Cc
, 0 },
66 { PNMFC_BCC
, "Bcc", 0, 0, 0, &PINMessage::Bcc
, 0 },
67 { PNMFC_FROM
, "From", 0, 0, 0, &PINMessage::From
, 0 },
68 { PNMFC_SUBJECT
, "Subject", 0, 0, &PINMessage::Subject
, 0, 0 },
69 { PNMFC_BODY
, "Body", 0, 0, &PINMessage::Body
, 0, 0 },
70 { PNMFC_END
, "End of List", 0, 0, 0, 0, 0 }
73 PINMessage::PINMessage()
77 PINMessage::~PINMessage()
81 const unsigned char* PINMessage::ParseField(const unsigned char *begin
,
82 const unsigned char *end
)
84 const CommonField
*field
= (const CommonField
*) begin
;
86 // advance and check size
87 begin
+= COMMON_FIELD_HEADER_SIZE
+ btohs(field
->size
);
88 if( begin
> end
) // if begin==end, we are ok
91 if( !btohs(field
->size
) ) // if field has no size, something's up
94 // cycle through the type table
95 for( FieldLink
<PINMessage
> *b
= PINMessageFieldLinks
;
99 if( b
->type
== field
->type
) {
101 // parse regular string
102 std::string
&s
= this->*(b
->strMember
);
103 s
.assign((const char *)field
->u
.raw
, btohs(field
->size
)-1);
104 return begin
; // done!
106 else if( b
->addrMember
) {
107 // parse email address
108 // get dual name+addr string first
109 const char *fa
= (const char*)field
->u
.addr
.addr
;
110 std::string
dual(fa
, btohs(field
->size
) - sizeof(field
->u
.addr
.unknown
));
112 // assign first string, using null terminator...letting std::string add it for us if it doesn't exist
113 Address
&a
= this->*(b
->addrMember
);
114 a
.Name
= dual
.c_str();
116 // assign second string, using first size as starting point
117 a
.Email
= dual
.c_str() + a
.Name
.size() + 1;
123 // handle special cases
124 switch( field
->type
)
127 MessageRecordId
= field
->u
.uint32
;
131 // if still not handled, add to the Unknowns list
133 uf
.type
= field
->type
;
134 uf
.data
.assign((const char*)field
->u
.raw
, btohs(field
->size
));
135 Unknowns
.push_back(uf
);
140 void PINMessage::ParseHeader(const Data
&data
, size_t &offset
)
142 // we skip the "header" since we don't know what to do with it yet
143 // FIXME - we are using a Message (email) record header size
144 // for a PIN Message record... this is not necessarily guaranteed
145 // to be the same... someday we could use some more info on
146 // the message record header and pin message record header
147 offset
+= MESSAGE_RECORD_HEADER_SIZE
;
150 void PINMessage::ParseFields(const Data
&data
, size_t &offset
)
152 const unsigned char *finish
= ParseCommonFields(*this,
153 data
.GetData() + offset
, data
.GetData() + data
.GetSize());
154 offset
+= finish
- (data
.GetData() + offset
);
157 void PINMessage::BuildHeader(Data
&data
, size_t &offset
) const
159 throw std::logic_error("PINMessage::BuildHeader not yet implemented");
162 void PINMessage::BuildFields(Data
&data
, size_t &offset
) const
164 throw std::logic_error("PINMessage::BuildFields not yet implemented");
167 void PINMessage::Clear()
181 // dump message in mbox format
182 void PINMessage::Dump(std::ostream
&os
) const
184 os
<< "Record ID (" << MessageRecordId
<< ")\n";
185 if( From
.Name
.size()) {
186 os
<< " From: " << From
.Name
<< " <" << From
.Email
<< ">\n";
188 if( To
.Name
.size()) {
189 os
<< " To: " << To
.Name
<< " <" << To
.Email
<< ">\n";
191 if( Cc
.Name
.size()) {
192 os
<< " Cc: " << Cc
.Name
<< " <" << Cc
.Email
<< ">\n";
194 if( Bcc
.Name
.size()) {
195 os
<< " Bcc: " << Bcc
.Name
<< " <" << Bcc
.Email
<< ">\n";
199 os
<< " Subject: " << Subject
<< "\n";
201 os
<< " Subject: <>\n";
204 for( std::string::const_iterator i
= Body
.begin();
205 i
!= Body
.end() && *i
;