--- /dev/null
+/*
+ * 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
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "VMessage.h"
+
+#include "EventTypes/SMS.h"
+#include "Factory.h"
+#include "VCard.h"
+#include "VEnvelope.h"
+#include "VBody.h"
+
+#include <QDateTime>
+#include <QTextStream>
+
+#include <QDebug>
+
+using namespace EventParsers::VMGEntities;
+
+VMessage::VMessage(const SMSEntity* parent) :
+ SMSEntity(parent), m_Version(1.1)
+{
+}
+
+//VMessage::VMessage(QTextStream& stream)
+//{
+//}
+
+VMessage::VMessage(const SMSEntity* parent, float version) :
+ SMSEntity(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");
+ 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(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(this);
+
+ // Add in the empty vcard for outgoing messages
+ if(event.Destination() == EventTypes::SMS::SENT)
+ {
+ VCard(this, 2.1, VCard::VCARD_LOCAL).Write(stream, event);
+
+ msgEnvelope.getContentWriters().append(new VCard(&msgEnvelope, 2.1, VCard::VCARD_REMOTE));
+
+ VEnvelope *bodyEnvelope = new VEnvelope(this);
+ bodyEnvelope->getContentWriters().append(new VBody(bodyEnvelope));
+ msgEnvelope.getContentWriters().append(bodyEnvelope);
+ }
+ else
+ {
+ VCard(this, 2.1, VCard::VCARD_REMOTE).Write(stream, event);
+
+ msgEnvelope.getContentWriters().append(new VBody(&msgEnvelope));
+ }
+
+ msgEnvelope.Write(stream, event);
+
+ stream << "END:VMSG\n";
+}