1 /*
2 Kopete Oscar Protocol
3 oscarmessage.cpp - Oscar Message Object
4
5 Copyright (c) 2005 Matt Rogers <mattr@kde.org>
6 Copyright (c) 2005 Conrad Hoffmann <conrausch@gmx.de>
7 Copyright (c) 2006-2007 Roman Jarosz <kedgedev@centrum.cz>
8
9 Kopete (c) 2002-2007 by the Kopete developers <kopete-devel@kde.org>
10
11 *************************************************************************
12 * *
13 * This library is free software; you can redistribute it and/or *
14 * modify it under the terms of the GNU Lesser General Public *
15 * License as published by the Free Software Foundation; either *
16 * version 2 of the License, or (at your option) any later version. *
17 * *
18 *************************************************************************
19 */
20
21 #include "oscarmessage.h"
22
23 #include <QTextCodec>
24 #include <QByteArray>
25 #include <QSharedData>
26
27 #include "oscarmessageplugin.h"
28
29 namespace Oscar
30 {
31
32 class Message::MessagePrivate : public QSharedData
33 {
34 public:
MessagePrivate()35 MessagePrivate()
36 : QSharedData()
37 {
38 channel = -1;
39 properties = 0;
40 messageType = 0;
41 requestType = 0;
42 port = 0;
43 requestNumber = 1;
44 protocolVersion = 0;
45 channel2Counter = 0;
46 encoding = UserDefined;
47 fileSize = 0;
48 fileCount = 0;
49 plugin = 0;
50 id = 0;
51 }
MessagePrivate(const MessagePrivate & other)52 MessagePrivate( const MessagePrivate &other )
53 : QSharedData( other )
54 {
55 sender = other.sender;
56 receiver = other.receiver;
57 channel = other.channel;
58 properties = other.properties;
59 messageType = other.messageType;
60 requestType = other.requestType;
61 port = other.port;
62 requestNumber = other.requestNumber;
63 protocolVersion = other.protocolVersion;
64 channel2Counter = other.channel2Counter;
65 icbmCookie = other.icbmCookie;
66 proxy = other.proxy;
67 textArray = other.textArray;
68 timestamp = other.timestamp;
69 exchange = other.exchange;
70 chatRoom = other.chatRoom;
71 encoding = other.encoding;
72 fileName = other.fileName;
73 fileSize = other.fileSize;
74 fileCount = other.fileCount;
75 id = other.id;
76
77 if ( other.plugin )
78 plugin = new MessagePlugin(*other.plugin);
79 else
80 plugin = 0;
81 }
82
~MessagePrivate()83 ~MessagePrivate()
84 {
85 delete plugin;
86 }
87
88 QString sender;
89 QString receiver;
90 int channel;
91 int properties;
92 int messageType;
93 int requestType;
94 int port;
95 int requestNumber;
96 int protocolVersion;
97 int channel2Counter;
98 QByteArray icbmCookie;
99 QByteArray proxy;
100 QByteArray textArray;
101 QDateTime timestamp;
102 WORD exchange;
103 QString chatRoom;
104 Encoding encoding;
105 QString fileName;
106 DWORD fileSize;
107 WORD fileCount;
108 MessagePlugin* plugin;
109 uint id;
110 };
111
Message()112 Message::Message()
113 : d( new MessagePrivate )
114 {
115 }
116 /*
117 Message::Message( Encoding messageEncoding, const QByteArray& messageText, int channel, int properties, QDateTime timestamp )
118 : d( new MessagePrivate )
119 {
120 d->channel = channel;
121 d->properties = properties;
122 d->textArray = messageText;
123 d->timestamp = timestamp;
124 d->encoding = messageEncoding;
125 }
126
127 Message::Message( Encoding messageEncoding, const QString& messageText, int channel, int properties, QDateTime timestamp, QTextCodec* codec )
128 : d( new MessagePrivate )
129 {
130 d->channel = channel;
131 d->properties = properties;
132 d->timestamp = timestamp;
133
134 setText( messageEncoding, messageText, codec );
135 }
136 */
Message(const Message & m)137 Message::Message( const Message& m )
138 : d( m.d )
139 {
140 }
141
operator =(const Message & m)142 Message& Message::operator=( const Message& m )
143 {
144 d = m.d;
145 return *this;
146 }
147
~Message()148 Message::~Message()
149 {
150 }
151
sender() const152 QString Message::sender() const
153 {
154 return d->sender;
155 }
156
setSender(const QString & sender)157 void Message::setSender( const QString& sender )
158 {
159 d->sender = sender;
160 }
161
receiver() const162 QString Message::receiver() const
163 {
164 return d->receiver;
165 }
166
setReceiver(const QString & receiver)167 void Message::setReceiver( const QString& receiver )
168 {
169 d->receiver = receiver;
170 }
171
textArray() const172 QByteArray Message::textArray() const
173 {
174 return d->textArray;
175 }
176
text(QTextCodec * codec) const177 QString Message::text( QTextCodec *codec ) const
178 {
179 switch ( d->encoding )
180 {
181 case Message::UserDefined:
182 return codec->toUnicode( d->textArray );
183 case Message::ASCII:
184 return QString::fromAscii( d->textArray.data(), d->textArray.size() );
185 case Message::LATIN1:
186 return QString::fromLatin1( d->textArray.data(), d->textArray.size() );
187 case Message::UTF8:
188 return QString::fromUtf8( d->textArray.data(), d->textArray.size() );
189 case Message::UCS2:
190 {
191 uint len = d->textArray.size() / 2;
192 QString result;
193 result.resize( len );
194 QByteArray::ConstIterator p = d->textArray.begin();
195 for ( uint i = 0; i < len; i++)
196 {
197 char row = *p++;
198 char cell = *p++;
199 result[i] = QChar( cell, row );
200 }
201 //check if last character isn't null
202 if ( result.at(len-1).isNull() )
203 result.resize( len - 1 );
204
205 return result;
206 }
207 default:
208 break; // Should never happen.
209 }
210 return QString();
211 //FIXME: warn at least with kdWarning if an unrecognised encoding style was seen.
212 }
213
encodingForText(const QString & newText,bool allowUCS2)214 Message::Encoding Message::encodingForText( const QString& newText, bool allowUCS2 )
215 {
216 Message::Encoding encoding = Message::ASCII;
217 const QChar *ch = newText.constData();
218 const int len = newText.length();
219
220 for ( int i = 0; i < len; ++i )
221 {
222 if ( ch[i] > 0xff )
223 {
224 encoding = ( allowUCS2 ) ? Message::UCS2 : Message::UserDefined;
225 break;
226 }
227 else if ( encoding == Message::ASCII && ch[i] > 0x7f )
228 {
229 encoding = Message::LATIN1;
230 }
231 }
232
233 return encoding;
234 }
235
setText(Message::Encoding newEncoding,const QString & newText,QTextCodec * codec)236 void Message::setText( Message::Encoding newEncoding, const QString& newText, QTextCodec* codec )
237 {
238 uint len;
239 switch ( newEncoding )
240 {
241 case Message::UserDefined:
242 // Message::setTextArray( const QCString& )
243 // strips trailing null byte automatically.
244 setTextArray( codec->fromUnicode( newText ) );
245 break;
246 case Message::ASCII:
247 setTextArray( newText.toAscii() );
248 break;
249 case Message::LATIN1:
250 setTextArray( newText.toLatin1() );
251 break;
252 case Message::UTF8:
253 // Message::setTextArray( const QCString& )
254 // strips trailing null byte automatically.
255 setTextArray( newText.toUtf8() );
256 break;
257 case Message::UCS2:
258 {
259 len = newText.length();
260 d->textArray.resize( len * 2 );
261 QByteArray::Iterator p = d->textArray.begin();
262 for ( uint i = 0; i < len; i++)
263 {
264 *p++ = newText[i].row();
265 *p++ = newText[i].cell();
266 }
267 break;
268 }
269 default:
270 break; // Should never happen.
271 }
272 d->encoding = newEncoding;
273 }
274
setTextArray(const QByteArray & newTextArray)275 void Message::setTextArray( const QByteArray& newTextArray )
276 {
277 d->textArray = newTextArray;
278 }
279
properties() const280 int Message::properties() const
281 {
282 return d->properties;
283 }
284
addProperty(int prop)285 void Message::addProperty( int prop )
286 {
287 d->properties = d->properties | prop;
288 }
289
hasProperty(int prop) const290 bool Message::hasProperty( int prop ) const
291 {
292 if ( ( d->properties & prop ) == 0 )
293 return false;
294 else
295 return true;
296 }
297
channel() const298 int Message::channel() const
299 {
300 return d->channel;
301 }
302
setChannel(int newChannel)303 void Message::setChannel( int newChannel )
304 {
305 d->channel = newChannel;
306 }
307
timestamp() const308 QDateTime Message::timestamp() const
309 {
310 return d->timestamp;
311 }
312
setTimestamp(QDateTime ts)313 void Message::setTimestamp( QDateTime ts )
314 {
315 d->timestamp = ts;
316 }
317
icbmCookie() const318 QByteArray Message::icbmCookie() const
319 {
320 return d->icbmCookie;
321 }
322
setIcbmCookie(const QByteArray & cookie)323 void Message::setIcbmCookie( const QByteArray& cookie )
324 {
325 d->icbmCookie = cookie;
326 }
327
protocolVersion() const328 int Message::protocolVersion() const
329 {
330 return d->protocolVersion;
331 }
332
setProtocolVersion(int version)333 void Message::setProtocolVersion( int version )
334 {
335 d->protocolVersion = version;
336 }
337
channel2Counter() const338 int Message::channel2Counter() const
339 {
340 return d->channel2Counter;
341 }
342
setChannel2Counter(int value)343 void Message::setChannel2Counter( int value )
344 {
345 d->channel2Counter = value;
346 }
347
messageType() const348 int Message::messageType() const
349 {
350 return d->messageType;
351 }
352
setMessageType(int type)353 void Message::setMessageType( int type )
354 {
355 d->messageType = type;
356 }
357
requestType() const358 int Message::requestType() const
359 {
360 return d->requestType;
361 }
362
setRequestType(int type)363 void Message::setRequestType( int type )
364 {
365 d->requestType = type;
366 }
367
port() const368 int Message::port() const
369 {
370 return d->port;
371 }
372
setPort(int port)373 void Message::setPort( int port )
374 {
375 d->port = port;
376 }
377
proxy() const378 QByteArray Message::proxy() const
379 {
380 return d->proxy;
381 }
382
setProxy(QByteArray proxy)383 void Message::setProxy( QByteArray proxy )
384 {
385 d->proxy = proxy;
386 }
387
requestNumber() const388 int Message::requestNumber() const
389 {
390 return d->requestNumber;
391 }
392
setRequestNumber(int n)393 void Message::setRequestNumber( int n )
394 {
395 d->requestNumber = n;
396 }
397
fileName() const398 QString Message::fileName() const
399 {
400 return d->fileName;
401 }
402
filesSize() const403 DWORD Message::filesSize() const
404 {
405 return d->fileSize;
406 }
407
fileCount() const408 WORD Message::fileCount() const
409 {
410 return d->fileCount;
411 }
412
setFileName(const QString & name)413 void Message::setFileName( const QString &name )
414 {
415 d->fileName = name;
416 }
417
setFilesSize(DWORD size)418 void Message::setFilesSize( DWORD size )
419 {
420 d->fileSize = size;
421 }
422
setFileCount(WORD count)423 void Message::setFileCount( WORD count )
424 {
425 d->fileCount = count;
426 }
427
exchange() const428 WORD Message::exchange() const
429 {
430 return d->exchange;
431 }
432
setExchange(WORD exchange)433 void Message::setExchange( WORD exchange )
434 {
435 d->exchange = exchange;
436 }
437
chatRoom() const438 QString Message::chatRoom() const
439 {
440 return d->chatRoom;
441 }
442
setChatRoom(const QString & room)443 void Message::setChatRoom( const QString& room )
444 {
445 d->chatRoom = room;
446 }
447
encoding() const448 Message::Encoding Message::encoding() const
449 {
450 return d->encoding;
451 }
452
setEncoding(Message::Encoding newEncoding)453 void Message::setEncoding( Message::Encoding newEncoding )
454 {
455 d->encoding = newEncoding;
456 }
457
plugin() const458 MessagePlugin* Message::plugin() const
459 {
460 return d->plugin;
461 }
462
setPlugin(MessagePlugin * plugin)463 void Message::setPlugin( MessagePlugin* plugin )
464 {
465 if ( d->plugin )
466 delete d->plugin;
467
468 d->plugin = plugin;
469 }
470
id() const471 uint Message::id() const
472 {
473 return d->id;
474 }
475
setId(uint id)476 void Message::setId( uint id )
477 {
478 d->id = id;
479 }
480
operator bool() const481 Message::operator bool() const
482 {
483 return d->channel != -1;
484 }
485
486 }
487
488