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 converted = qdbus_cast<QVariantMap>(dbusValue);
145 return QVariantMap();
150 QVariantMap returnValue;
151 QVariantMap::const_iterator i;
152 for (i = converted.constBegin(); i != converted.constEnd(); ++i) {
153 if (qstrcmp(i.value().typeName(),
"QDBusArgument") == 0) {
154 QVariantMap convertedValue = expandDBusArgumentValue(i.value(), success);
155 if (success ==
false) {
157 return QVariantMap();
159 returnValue.insert(i.key(), convertedValue);
161 returnValue.insert(i.key(), i.value());
168 static QVariantMap filterOutComplexTypes(
const QVariantMap &map)
170 QVariantMap filteredMap;
171 QVariantMap::const_iterator i;
172 for (i = map.constBegin(); i != map.constEnd(); i++) {
173 if (qstrcmp(i.value().typeName(),
"QDBusArgument") == 0) {
175 QVariantMap convertedMap = expandDBusArgumentValue(i.value(), &success);
176 if (success ==
false) {
182 BLAME() <<
"Found non-map QDBusArgument in data; skipping.";
185 filteredMap.insert(i.key(), convertedMap);
187 filteredMap.insert(i.key(), i.value());
193 QByteArray BlobIOHandler::variantMapToByteArray(
const QVariantMap &map)
196 if (!buffer.open(QIODevice::WriteOnly))
197 BLAME() <<
"Buffer opening failed.";
199 QDataStream stream(&buffer);
200 stream << filterOutComplexTypes(map);
203 return buffer.data();
206 QVariantMap BlobIOHandler::byteArrayToVariantMap(
const QByteArray &array)
208 QByteArray nonConst = array;
209 QBuffer buffer(&nonConst);
210 if (!buffer.open(QIODevice::ReadOnly))
211 BLAME() <<
"Buffer opening failed.";
214 QDataStream stream(&buffer);
222 QVector<QByteArray> BlobIOHandler::pageByteArray(
const QByteArray &array)
224 QVector<QByteArray> dataPages;
225 QByteArray ba = array;
226 QBuffer pagingBuffer(&ba);
228 if (!pagingBuffer.open(QIODevice::ReadOnly))
229 BLAME() <<
"Error while paging BLOB. Buffer opening failed.";
231 while (!pagingBuffer.atEnd()) {
232 QByteArray page = pagingBuffer.read(SIGNON_IPC_BUFFER_PAGE_SIZE);
233 dataPages.append(page);
235 pagingBuffer.close();
Error codes for ui interaction.