/*
* Copyright (C) 2011, Jamie Thompson
*
* 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 3 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 for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; If not, see
* .
*/
#include "VMessage.h"
#include "EventTypes/SMS.h"
#include "Factory.h"
#include "Settings.h"
#include "VBody.h"
#include "VCard.h"
#include "VEnvelope.h"
#include
#include
#include
using namespace EventParsers::VMGEntities;
VMessage::VMessage(const Settings &settings, const SMSEntity *parent) :
SMSEntity(settings, parent), m_Version(1.1)
{
}
//VMessage::VMessage(QTextStream& stream)
//{
//}
VMessage::VMessage(const Settings &settings, const SMSEntity *parent, float version) :
SMSEntity(settings, parent), m_Version(version)
{
}
VMessage::~VMessage()
{
}
bool VMessage::Read(const QString &initialLine, QTextStream &stream, EventTypes::SMS &event)
{
if(getParent() != NULL)
{
qDebug() << "Messages cannot be nested.";
return false;
}
bool hasEnded(false);
float version(0);
// Stream may or may not have a 'BEGIN' present. Swallow it if it's ours.
QString lineData(initialLine.length() > 0 ? initialLine : stream.readLine());
if(lineData.startsWith("BEGIN:"))
{
if(lineData != QString("BEGIN:") + getTagName())
{
qDebug() << "Invalid stream";
return false;
}
else // ...discard this line
lineData = stream.readLine();
}
do
{
if(lineData.startsWith("VERSION:"))
{
version = lineData.mid(lineData.indexOf(":")+1).toFloat();
}
else if(lineData.startsWith("X-IRMC-STATUS:"))
{
bool isRead(lineData.mid(lineData.indexOf(":") + 1) == "READ");
event.setIsRead(isRead);
}
else if(lineData.startsWith("X-IRMC-BOX:"))
{
QString box = lineData.mid(lineData.indexOf(":") + 1);
bool isOutgoing(box == "SENT");
// Early out once we know we're not processing this type of message
if((!isOutgoing && !CurrentSettings().ShouldProcess(Settings::INCOMING, EventTypes::EVENT_TYPE_SMS))
|| isOutgoing && !CurrentSettings().ShouldProcess(Settings::OUTGOING, EventTypes::EVENT_TYPE_SMS))
{
return false;
}
if (isOutgoing == false && box != "INBOX")
{
qDebug() << "Unexpected box: " << box;
return false;
}
event.setDestination(isOutgoing ? EventTypes::SMS::SENT : EventTypes::SMS::INBOX);
}
else if(lineData.startsWith("X-NOK-DT:"))
{
QDateTime timestamp(QDateTime::fromString(
lineData.mid(lineData.indexOf(":") + 1),
"yyyyMMddThhmmssZ"));
timestamp.setTimeSpec(Qt::UTC);
event.setTimestamp(timestamp);
}
else if(lineData.startsWith("BEGIN:"))
{
iReader* reader = Factory::Instantiate(CurrentSettings(), lineData, this);
bool valid(NULL != reader && reader->Read(lineData, stream, event));
delete reader;
// Quit processing if the nested content is not valid
if(!valid)
return valid;
}
else if(lineData.startsWith("END:"))
{
if(lineData != "END:VMSG")
{
qDebug() << getTagName() << " parser mismatch error" << lineData;
return false;
}
else
{
hasEnded = true;
break;
}
}
lineData = stream.readLine();
}while(!hasEnded && !stream.atEnd());
return true;
}
void VMessage::Write(QTextStream &stream, const EventTypes::SMS &event)
{
stream << "BEGIN:VMSG\n";
stream << "VERSION:" << m_Version << "\n";
stream << "X-IRMC-STATUS:" << ( event.IsRead() ? "READ" : "") << "\n";
stream << "X-IRMC-BOX:" << ( event.Destination() == EventTypes::SMS::SENT ? "SENT" : "INBOX") << "\n";
stream << "X-NOK-DT:" << event.Timestamp().toUTC().toString("yyyyMMddThhmmssZ") << "\n";
VEnvelope msgEnvelope(CurrentSettings(), this);
// Add in the empty vcard for outgoing messages
if(event.Destination() == EventTypes::SMS::SENT)
{
VCard(CurrentSettings(), this, 2.1, VCard::VCARD_LOCAL).Write(stream, event);
msgEnvelope.getContentWriters().append(new VCard(CurrentSettings(), &msgEnvelope, 2.1, VCard::VCARD_REMOTE));
VEnvelope *bodyEnvelope = new VEnvelope(CurrentSettings(), this);
bodyEnvelope->getContentWriters().append(new VBody(CurrentSettings(), bodyEnvelope));
msgEnvelope.getContentWriters().append(bodyEnvelope);
}
else
{
VCard(CurrentSettings(), this, 2.1, VCard::VCARD_REMOTE).Write(stream, event);
msgEnvelope.getContentWriters().append(new VBody(CurrentSettings(), &msgEnvelope));
}
msgEnvelope.Write(stream, event);
stream << "END:VMSG\n";
}