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);
68 QVector<QByteArray> pages = pageByteArray(ba);
69 for (
int i = 0; i < pages.count(); ++i)
75void BlobIOHandler::setReadNotificationEnabled(
bool enabled)
77 m_isReading = enabled;
79 if (m_readNotifier != 0) {
80 connect(m_readNotifier, SIGNAL(activated(
int)),
81 this, SLOT(readBlob()));
83 connect(m_readChannel, SIGNAL(readyRead()),
84 this, SLOT(readBlob()));
87 if (m_readNotifier != 0) {
88 disconnect(m_readNotifier, SIGNAL(activated(
int)),
89 this, SLOT(readBlob()));
91 disconnect(m_readChannel, SIGNAL(readyRead()),
92 this, SLOT(readBlob()));
97void BlobIOHandler::receiveData(
int expectedDataSize)
100 m_blobSize = expectedDataSize;
104 if (m_blobSize > SIGNON_IPC_BUFFER_PAGE_SIZE)
105 setReadNotificationEnabled(
true);
110void BlobIOHandler::readBlob()
112 QDataStream in(m_readChannel);
114 QByteArray fractionBa;
116 m_blobBuffer.append(fractionBa);
119 if ((fractionBa.size() == 0) && (m_blobBuffer.size() < m_blobSize)) {
120 setReadNotificationEnabled(
false);
125 if (m_blobBuffer.size() == m_blobSize) {
126 QVariantMap sessionDataMap;
127 sessionDataMap = byteArrayToVariantMap(m_blobBuffer);
129 if (m_blobSize > SIGNON_IPC_BUFFER_PAGE_SIZE)
130 setReadNotificationEnabled(
false);
132 emit dataReceived(sessionDataMap);
136QVariantMap expandDBusArgumentValue(
const QVariant &value,
bool *success)
139 QDBusArgument dbusValue = value.value<QDBusArgument>();
140 QVariantMap converted;
141 if (dbusValue.currentType() == QDBusArgument::MapType &&
143 dbusValue.currentSignature() ==
"a{sv}") {
144 converted = qdbus_cast<QVariantMap>(dbusValue);
147 return QVariantMap();
152 QVariantMap returnValue;
153 QVariantMap::const_iterator i;
154 for (i = converted.constBegin(); i != converted.constEnd(); ++i) {
155 if (qstrcmp(i.value().typeName(),
"QDBusArgument") == 0) {
156 QVariantMap convertedValue = expandDBusArgumentValue(i.value(), success);
157 if (*success ==
false) {
159 return QVariantMap();
161 returnValue.insert(i.key(), convertedValue);
163 returnValue.insert(i.key(), i.value());
170static QVariantMap filterOutComplexTypes(
const QVariantMap &map)
172 QVariantMap filteredMap;
173 QVariantMap::const_iterator i;
174 for (i = map.constBegin(); i != map.constEnd(); i++) {
175 if (qstrcmp(i.value().typeName(),
"QDBusArgument") == 0) {
177 QVariantMap convertedMap = expandDBusArgumentValue(i.value(), &success);
178 if (success ==
false) {
184 BLAME() <<
"Found non-map QDBusArgument in data; skipping.";
187 filteredMap.insert(i.key(), convertedMap);
189 filteredMap.insert(i.key(), i.value());
195QByteArray BlobIOHandler::variantMapToByteArray(
const QVariantMap &map)
198 if (!buffer.open(QIODevice::WriteOnly))
199 BLAME() <<
"Buffer opening failed.";
201 QDataStream stream(&buffer);
202 stream << filterOutComplexTypes(map);
205 return buffer.data();
208QVariantMap BlobIOHandler::byteArrayToVariantMap(
const QByteArray &array)
210 QByteArray nonConst = array;
211 QBuffer buffer(&nonConst);
212 if (!buffer.open(QIODevice::ReadOnly))
213 BLAME() <<
"Buffer opening failed.";
216 QDataStream stream(&buffer);
224QVector<QByteArray> BlobIOHandler::pageByteArray(
const QByteArray &array)
226 QVector<QByteArray> dataPages;
227 QByteArray ba = array;
228 QBuffer pagingBuffer(&ba);
230 if (!pagingBuffer.open(QIODevice::ReadOnly))
231 BLAME() <<
"Error while paging BLOB. Buffer opening failed.";
233 while (!pagingBuffer.atEnd()) {
234 QByteArray page = pagingBuffer.read(SIGNON_IPC_BUFFER_PAGE_SIZE);
235 dataPages.append(page);
237 pagingBuffer.close();
Error codes for ui interaction.