24 #include "blobiohandler.h"
26 #include <QDBusArgument>
30 #include "SignOn/signonplugincommon.h"
32 #define SIGNON_IPC_BUFFER_PAGE_SIZE 16384
36 BlobIOHandler::BlobIOHandler(QIODevice *readChannel,
37 QIODevice *writeChannel,
40 m_readChannel(readChannel),
41 m_writeChannel(writeChannel),
47 void BlobIOHandler::setReadChannelSocketNotifier(QSocketNotifier *notifier)
52 m_readNotifier = notifier;
55 bool BlobIOHandler::sendData(
const QVariantMap &map)
57 if (m_writeChannel == 0) {
58 TRACE() <<
"NULL write channel.";
62 QDataStream stream(m_writeChannel);
63 QByteArray ba = variantMapToByteArray(map);
66 QVector<QByteArray> pages = pageByteArray(ba);
67 for (
int i = 0; i < pages.count(); ++i)
73 void BlobIOHandler::setReadNotificationEnabled(
bool enabled)
76 if (m_readNotifier != 0) {
77 m_readNotifier->setEnabled(
true);
78 connect(m_readNotifier, SIGNAL(activated(
int)),
79 this, SLOT(readBlob()));
81 connect(m_readChannel, SIGNAL(readyRead()),
82 this, SLOT(readBlob()));
85 if (m_readNotifier != 0) {
86 disconnect(m_readNotifier, SIGNAL(activated(
int)),
87 this, SLOT(readBlob()));
88 m_readNotifier->setEnabled(
false);
90 disconnect(m_readChannel, SIGNAL(readyRead()),
91 this, SLOT(readBlob()));
96 void BlobIOHandler::receiveData(
int expectedDataSize)
99 m_blobSize = expectedDataSize;
103 if (m_blobSize > SIGNON_IPC_BUFFER_PAGE_SIZE)
104 setReadNotificationEnabled(
true);
109 void BlobIOHandler::readBlob()
111 QDataStream in(m_readChannel);
113 QByteArray fractionBa;
115 m_blobBuffer.append(fractionBa);
118 if ((fractionBa.size() == 0) && (m_blobBuffer.size() < m_blobSize)) {
119 setReadNotificationEnabled(
false);
124 if (m_blobBuffer.size() == m_blobSize) {
125 QVariantMap sessionDataMap;
126 sessionDataMap = byteArrayToVariantMap(m_blobBuffer);
128 if (m_blobSize > SIGNON_IPC_BUFFER_PAGE_SIZE)
129 setReadNotificationEnabled(
false);
131 emit dataReceived(sessionDataMap);
135 QVariantMap expandDBusArgumentValue(
const QVariant &value,
bool *success)
138 QDBusArgument dbusValue = value.value<QDBusArgument>();
139 QVariantMap converted;
140 if (dbusValue.currentType() == QDBusArgument::MapType &&
142 dbusValue.currentSignature() ==
"a{sv}") {
143 converted = qdbus_cast<QVariantMap>(dbusValue);
146 return QVariantMap();
151 QVariantMap returnValue;
152 QVariantMap::const_iterator i;
153 for (i = converted.constBegin(); i != converted.constEnd(); ++i) {
154 if (qstrcmp(i.value().typeName(),
"QDBusArgument") == 0) {
155 QVariantMap convertedValue = expandDBusArgumentValue(i.value(), success);
156 if (*success ==
false) {
158 return QVariantMap();
160 returnValue.insert(i.key(), convertedValue);
162 returnValue.insert(i.key(), i.value());
169 static QVariantMap filterOutComplexTypes(
const QVariantMap &map)
171 QVariantMap filteredMap;
172 QVariantMap::const_iterator i;
173 for (i = map.constBegin(); i != map.constEnd(); i++) {
174 if (qstrcmp(i.value().typeName(),
"QDBusArgument") == 0) {
176 QVariantMap convertedMap = expandDBusArgumentValue(i.value(), &success);
177 if (success ==
false) {
183 BLAME() <<
"Found non-map QDBusArgument in data; skipping.";
186 filteredMap.insert(i.key(), convertedMap);
188 filteredMap.insert(i.key(), i.value());
194 QByteArray BlobIOHandler::variantMapToByteArray(
const QVariantMap &map)
197 if (!buffer.open(QIODevice::WriteOnly))
198 BLAME() <<
"Buffer opening failed.";
200 QDataStream stream(&buffer);
201 stream << filterOutComplexTypes(map);
204 return buffer.data();
207 QVariantMap BlobIOHandler::byteArrayToVariantMap(
const QByteArray &array)
209 QByteArray nonConst = array;
210 QBuffer buffer(&nonConst);
211 if (!buffer.open(QIODevice::ReadOnly))
212 BLAME() <<
"Buffer opening failed.";
215 QDataStream stream(&buffer);
223 QVector<QByteArray> BlobIOHandler::pageByteArray(
const QByteArray &array)
225 QVector<QByteArray> dataPages;
226 QByteArray ba = array;
227 QBuffer pagingBuffer(&ba);
229 if (!pagingBuffer.open(QIODevice::ReadOnly))
230 BLAME() <<
"Error while paging BLOB. Buffer opening failed.";
232 while (!pagingBuffer.atEnd()) {
233 QByteArray page = pagingBuffer.read(SIGNON_IPC_BUFFER_PAGE_SIZE);
234 dataPages.append(page);
236 pagingBuffer.close();
Error codes for ui interaction.