24#include "blobiohandler.h"
26#include <QDBusArgument>
32#include "SignOn/signonplugincommon.h"
34#define SIGNON_IPC_BUFFER_PAGE_SIZE 16384
38BlobIOHandler::BlobIOHandler(QIODevice *readChannel,
39 QIODevice *writeChannel,
42 m_readChannel(readChannel),
43 m_writeChannel(writeChannel),
50void BlobIOHandler::setReadChannelSocketNotifier(QSocketNotifier *notifier)
55 m_readNotifier = notifier;
58bool BlobIOHandler::sendData(
const QVariantMap &map)
60 if (m_writeChannel == 0) {
61 TRACE() <<
"NULL write channel.";
65 QDataStream stream(m_writeChannel);
66 QByteArray ba = variantMapToByteArray(map);
68 stream << static_cast<int>(ba.size());
70 QVector<QByteArray> pages = pageByteArray(ba);
71 for (
int i = 0; i < pages.count(); ++i)
77void BlobIOHandler::setReadNotificationEnabled(
bool enabled)
79 m_isReading = enabled;
81 if (m_readNotifier != 0) {
82 connect(m_readNotifier, SIGNAL(activated(
int)),
83 this, SLOT(readBlob()));
85 connect(m_readChannel, SIGNAL(readyRead()),
86 this, SLOT(readBlob()));
89 if (m_readNotifier != 0) {
90 disconnect(m_readNotifier, SIGNAL(activated(
int)),
91 this, SLOT(readBlob()));
93 disconnect(m_readChannel, SIGNAL(readyRead()),
94 this, SLOT(readBlob()));
99void BlobIOHandler::receiveData(
int expectedDataSize)
101 m_blobBuffer.clear();
102 m_blobSize = expectedDataSize;
106 if (m_blobSize > SIGNON_IPC_BUFFER_PAGE_SIZE)
107 setReadNotificationEnabled(
true);
112void BlobIOHandler::readBlob()
114 QDataStream in(m_readChannel);
116 QByteArray fractionBa;
118 m_blobBuffer.append(fractionBa);
121 if ((fractionBa.size() == 0) && (m_blobBuffer.size() < m_blobSize)) {
122 setReadNotificationEnabled(
false);
127 if (m_blobBuffer.size() == m_blobSize) {
128 QVariantMap sessionDataMap;
129 sessionDataMap = byteArrayToVariantMap(m_blobBuffer);
131 if (m_blobSize > SIGNON_IPC_BUFFER_PAGE_SIZE)
132 setReadNotificationEnabled(
false);
134 emit dataReceived(sessionDataMap);
138QVariantMap expandDBusArgumentValue(
const QVariant &value,
bool *success)
141 QDBusArgument dbusValue = value.value<QDBusArgument>();
142 QVariantMap converted;
143 if (dbusValue.currentType() == QDBusArgument::MapType &&
145 dbusValue.currentSignature() ==
"a{sv}") {
146 converted = qdbus_cast<QVariantMap>(dbusValue);
149 return QVariantMap();
154 QVariantMap returnValue;
155 QVariantMap::const_iterator i;
156 for (i = converted.constBegin(); i != converted.constEnd(); ++i) {
157 if (qstrcmp(i.value().typeName(),
"QDBusArgument") == 0) {
158 QVariantMap convertedValue = expandDBusArgumentValue(i.value(), success);
159 if (*success ==
false) {
161 return QVariantMap();
163 returnValue.insert(i.key(), convertedValue);
165 returnValue.insert(i.key(), i.value());
172static QVariantMap filterOutComplexTypes(
const QVariantMap &map)
174 QVariantMap filteredMap;
175 QVariantMap::const_iterator i;
176 for (i = map.constBegin(); i != map.constEnd(); i++) {
177 if (qstrcmp(i.value().typeName(),
"QDBusArgument") == 0) {
179 QVariantMap convertedMap = expandDBusArgumentValue(i.value(), &success);
180 if (success ==
false) {
186 BLAME() <<
"Found non-map QDBusArgument in data; skipping.";
189 filteredMap.insert(i.key(), convertedMap);
191 filteredMap.insert(i.key(), i.value());
197QByteArray BlobIOHandler::variantMapToByteArray(
const QVariantMap &map)
200 if (!buffer.open(QIODevice::WriteOnly))
201 BLAME() <<
"Buffer opening failed.";
203 QDataStream stream(&buffer);
204 stream << filterOutComplexTypes(map);
207 return buffer.data();
210QVariantMap BlobIOHandler::byteArrayToVariantMap(
const QByteArray &array)
212 QByteArray nonConst = array;
213 QBuffer buffer(&nonConst);
214 if (!buffer.open(QIODevice::ReadOnly))
215 BLAME() <<
"Buffer opening failed.";
218 QDataStream stream(&buffer);
226QVector<QByteArray> BlobIOHandler::pageByteArray(
const QByteArray &array)
228 QVector<QByteArray> dataPages;
229 QByteArray ba = array;
230 QBuffer pagingBuffer(&ba);
232 if (!pagingBuffer.open(QIODevice::ReadOnly))
233 BLAME() <<
"Error while paging BLOB. Buffer opening failed.";
235 while (!pagingBuffer.atEnd()) {
236 QByteArray page = pagingBuffer.read(SIGNON_IPC_BUFFER_PAGE_SIZE);
237 dataPages.append(page);
239 pagingBuffer.close();
Error codes for ui interaction.