24#include "blobiohandler.h"
26#include <QDBusArgument>
31#include "SignOn/signonplugincommon.h"
33#define SIGNON_IPC_BUFFER_PAGE_SIZE 16384
37BlobIOHandler::BlobIOHandler(QIODevice *readChannel,
38 QIODevice *writeChannel,
41 m_readChannel(readChannel),
42 m_writeChannel(writeChannel),
49void BlobIOHandler::setReadChannelSocketNotifier(QSocketNotifier *notifier)
54 m_readNotifier = notifier;
57bool BlobIOHandler::sendData(
const QVariantMap &map)
59 if (m_writeChannel == 0) {
60 TRACE() <<
"NULL write channel.";
64 QDataStream stream(m_writeChannel);
65 QByteArray ba = variantMapToByteArray(map);
67 stream << static_cast<int>(ba.size());
69 QVector<QByteArray> pages = pageByteArray(ba);
70 for (
int i = 0; i < pages.count(); ++i)
76void BlobIOHandler::setReadNotificationEnabled(
bool enabled)
78 m_isReading = enabled;
80 if (m_readNotifier != 0) {
81 connect(m_readNotifier, SIGNAL(activated(
int)),
82 this, SLOT(readBlob()));
84 connect(m_readChannel, SIGNAL(readyRead()),
85 this, SLOT(readBlob()));
88 if (m_readNotifier != 0) {
89 disconnect(m_readNotifier, SIGNAL(activated(
int)),
90 this, SLOT(readBlob()));
92 disconnect(m_readChannel, SIGNAL(readyRead()),
93 this, SLOT(readBlob()));
98void BlobIOHandler::receiveData(
int expectedDataSize)
100 m_blobBuffer.clear();
101 m_blobSize = expectedDataSize;
105 if (m_blobSize > SIGNON_IPC_BUFFER_PAGE_SIZE)
106 setReadNotificationEnabled(
true);
111void BlobIOHandler::readBlob()
113 QDataStream in(m_readChannel);
115 in.startTransaction();
116 QByteArray fractionBa;
119 if (!in.commitTransaction()) {
120 setReadNotificationEnabled(
true);
126 m_blobBuffer.append(fractionBa);
129 if ((fractionBa.size() == 0) && (m_blobBuffer.size() < m_blobSize)) {
130 setReadNotificationEnabled(
false);
135 if (m_blobBuffer.size() == m_blobSize) {
136 QVariantMap sessionDataMap;
137 sessionDataMap = byteArrayToVariantMap(m_blobBuffer);
139 setReadNotificationEnabled(
false);
141 emit dataReceived(sessionDataMap);
145QVariantMap expandDBusArgumentValue(
const QVariant &value,
bool *success)
148 QDBusArgument dbusValue = value.value<QDBusArgument>();
149 QVariantMap converted;
150 if (dbusValue.currentType() == QDBusArgument::MapType &&
152 dbusValue.currentSignature() ==
"a{sv}") {
153 converted = qdbus_cast<QVariantMap>(dbusValue);
156 return QVariantMap();
161 QVariantMap returnValue;
162 QVariantMap::const_iterator i;
163 for (i = converted.constBegin(); i != converted.constEnd(); ++i) {
164 if (qstrcmp(i.value().typeName(),
"QDBusArgument") == 0) {
165 QVariantMap convertedValue = expandDBusArgumentValue(i.value(), success);
166 if (*success ==
false) {
168 return QVariantMap();
170 returnValue.insert(i.key(), convertedValue);
172 returnValue.insert(i.key(), i.value());
179static QVariantMap filterOutComplexTypes(
const QVariantMap &map)
181 QVariantMap filteredMap;
182 QVariantMap::const_iterator i;
183 for (i = map.constBegin(); i != map.constEnd(); i++) {
184 if (qstrcmp(i.value().typeName(),
"QDBusArgument") == 0) {
186 QVariantMap convertedMap = expandDBusArgumentValue(i.value(), &success);
187 if (success ==
false) {
193 BLAME() <<
"Found non-map QDBusArgument in data; skipping.";
196 filteredMap.insert(i.key(), convertedMap);
198 filteredMap.insert(i.key(), i.value());
204QByteArray BlobIOHandler::variantMapToByteArray(
const QVariantMap &map)
207 if (!buffer.open(QIODevice::WriteOnly))
208 BLAME() <<
"Buffer opening failed.";
210 QDataStream stream(&buffer);
211 stream << filterOutComplexTypes(map);
214 return buffer.data();
217QVariantMap BlobIOHandler::byteArrayToVariantMap(
const QByteArray &array)
219 QByteArray nonConst = array;
220 QBuffer buffer(&nonConst);
221 if (!buffer.open(QIODevice::ReadOnly))
222 BLAME() <<
"Buffer opening failed.";
225 QDataStream stream(&buffer);
233QVector<QByteArray> BlobIOHandler::pageByteArray(
const QByteArray &array)
235 QVector<QByteArray> dataPages;
236 QByteArray ba = array;
237 QBuffer pagingBuffer(&ba);
239 if (!pagingBuffer.open(QIODevice::ReadOnly))
240 BLAME() <<
"Error while paging BLOB. Buffer opening failed.";
242 while (!pagingBuffer.atEnd()) {
243 QByteArray page = pagingBuffer.read(SIGNON_IPC_BUFFER_PAGE_SIZE);
244 dataPages.append(page);
246 pagingBuffer.close();
Error codes for ui interaction.