Added CSV parsing and export of Symbian-format Event logs that have had their tables...
[qwerkisync] / Attachment.cpp
1 /*
2  * Copyright (C) 2011, Jamie Thompson
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License as published by the Free Software Foundation; either
7  * version 3 of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this program; If not, see
16  * <http://www.gnu.org/licenses/>.
17  */
18
19 #include "Attachment.h"
20
21 #include <QCryptographicHash>
22 #include <QDir>
23 #include <QFile>
24 #include <QTextStream>
25
26 #include <stdexcept>
27
28 #include <sys/mman.h>
29 #include <fcntl.h>
30
31 #include <rtcom-eventlogger/eventlogger-attach-iter.h>
32
33 Attachment::Attachment(QString path, QString description) :
34         m_Path(path),
35         m_Description(description),
36         m_FileHandle(m_Path),
37         m_DeleteFileOnDestruction(true)
38 {
39         if(m_FileHandle.open(QFile::WriteOnly | QFile::Unbuffered))
40         {
41                 m_Stream = new QTextStream(&m_FileHandle);
42                 if(m_Stream != NULL)
43                 {
44                         m_Stream->setCodec("UTF8");
45                 }
46                 else
47                         throw std::runtime_error(QString("Unable to create attachment stream: '%1'").arg(m_Path).toStdString());
48         }
49         else
50                 throw std::runtime_error(QString("Unable to open attachment file: '%1'. The reason was: %2").arg(m_Path).arg(m_FileHandle.errorString()).toStdString());
51 }
52
53 Attachment::~Attachment()
54 {
55         if(m_Stream != NULL)
56                 delete m_Stream;
57
58         m_FileHandle.close();
59
60         if(m_DeleteFileOnDestruction && m_Path.length() > 0)
61                 QFile::remove(m_Path);
62 }
63
64 Attachment::Attachment(const _RTComElAttachment& attachment) :
65         m_Path(attachment.path),
66         m_Description(attachment.desc),
67         m_FileHandle(m_Path),
68         m_DeleteFileOnDestruction(attachment.id < 1) // Don't delete the file if we have a valid attachment ID
69 {
70         if(m_FileHandle.open(QFile::ReadWrite))
71         {
72                 m_Stream = new QTextStream(&m_FileHandle);
73                 if(m_Stream != NULL)
74                 {
75                         m_Stream->setCodec("UTF8");
76                 }
77                 else
78                         throw std::runtime_error(QString("Unable to create attachment stream: '%1'").arg(m_Path).toStdString());
79         }
80         else
81                 throw std::runtime_error(QString("Unable to open attachment file: '%1'. The reason was: %2").arg(m_Path).arg(m_FileHandle.errorString()).toStdString());
82 }
83
84 RTComElAttachment * Attachment::toRTComAttachment() const
85 {
86         RTComElAttachment *attachment(
87                 rtcom_el_attachment_new(
88                         g_strdup(Path().toUtf8()),
89                         g_strdup(Description().toUtf8())));
90         return attachment;
91 }
92
93 void Attachment::freeRTComContents(RTComElAttachment &attachment)
94 {
95         g_free(attachment.path);
96         attachment.path = NULL;
97
98         g_free(attachment.desc);
99         attachment.desc = NULL;
100 }
101
102 const uint Attachment::HashCode() const
103 {
104         qDebug() << "Hashing attachment: " << Path();
105
106         QFile file(Path());
107         if(file.open(QFile::ReadOnly))
108         {
109                 uchar *memory(file.map(0, file.size()));
110                 if (memory)
111                 {
112                         QByteArray data;
113                         data.fromRawData((char*)memory, file.size());
114                         uint hashcode = QCryptographicHash::hash(data, QCryptographicHash::Md5).toUInt();
115
116                         file.unmap(memory);
117
118                         return hashcode;
119                 }
120                 else
121                         throw std::runtime_error(QString("Unable to map attachment file: %1").arg(Path()).toStdString());
122         }
123         else
124                 throw std::runtime_error(QString("Unable to open attachment file: '%1'. The reason was: %2").arg(m_Path).arg(m_FileHandle.errorString()).toStdString());
125 }
126
127 QDebug operator<<(QDebug dbg, Attachment& attachment)
128 {
129         dbg.nospace() << "Path:\t" << attachment.Path() << "\n";
130         dbg.nospace() << "Desc:\t" << attachment.Description() << "\n";
131
132         return dbg;
133 }