24 #include "blobiohandler.h" 26 #include <QDBusArgument> 28 #include <QDataStream> 31 #include "SignOn/signonplugincommon.h" 33 #define SIGNON_IPC_BUFFER_PAGE_SIZE 16384 37 BlobIOHandler::BlobIOHandler(QIODevice *readChannel,
38 QIODevice *writeChannel,
41 m_readChannel(readChannel),
42 m_writeChannel(writeChannel),
49 void BlobIOHandler::setReadChannelSocketNotifier(QSocketNotifier *notifier)
54 m_readNotifier = notifier;
57 bool 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)
76 void 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()));
98 void BlobIOHandler::receiveData(
int expectedDataSize)
100 m_blobBuffer.clear();
101 m_blobSize = expectedDataSize;
105 if (m_blobSize > SIGNON_IPC_BUFFER_PAGE_SIZE)
106 setReadNotificationEnabled(
true);
111 void BlobIOHandler::readBlob()
113 QDataStream in(m_readChannel);
115 QByteArray fractionBa;
117 m_blobBuffer.append(fractionBa);
120 if ((fractionBa.size() == 0) && (m_blobBuffer.size() < m_blobSize)) {
121 setReadNotificationEnabled(
false);
126 if (m_blobBuffer.size() == m_blobSize) {
127 QVariantMap sessionDataMap;
128 sessionDataMap = byteArrayToVariantMap(m_blobBuffer);
130 if (m_blobSize > SIGNON_IPC_BUFFER_PAGE_SIZE)
131 setReadNotificationEnabled(
false);
133 emit dataReceived(sessionDataMap);
137 QVariantMap expandDBusArgumentValue(
const QVariant &value,
bool *success)
140 QDBusArgument dbusValue = value.value<QDBusArgument>();
141 QVariantMap converted;
142 if (dbusValue.currentType() == QDBusArgument::MapType &&
144 dbusValue.currentSignature() ==
"a{sv}") {
145 converted = qdbus_cast<QVariantMap>(dbusValue);
148 return QVariantMap();
153 QVariantMap returnValue;
154 QVariantMap::const_iterator i;
155 for (i = converted.constBegin(); i != converted.constEnd(); ++i) {
156 if (qstrcmp(i.value().typeName(),
"QDBusArgument") == 0) {
157 QVariantMap convertedValue = expandDBusArgumentValue(i.value(), success);
158 if (*success ==
false) {
160 return QVariantMap();
162 returnValue.insert(i.key(), convertedValue);
164 returnValue.insert(i.key(), i.value());
171 static QVariantMap filterOutComplexTypes(
const QVariantMap &map)
173 QVariantMap filteredMap;
174 QVariantMap::const_iterator i;
175 for (i = map.constBegin(); i != map.constEnd(); i++) {
176 if (qstrcmp(i.value().typeName(),
"QDBusArgument") == 0) {
178 QVariantMap convertedMap = expandDBusArgumentValue(i.value(), &success);
179 if (success ==
false) {
185 BLAME() <<
"Found non-map QDBusArgument in data; skipping.";
188 filteredMap.insert(i.key(), convertedMap);
190 filteredMap.insert(i.key(), i.value());
196 QByteArray BlobIOHandler::variantMapToByteArray(
const QVariantMap &map)
199 if (!buffer.open(QIODevice::WriteOnly))
200 BLAME() <<
"Buffer opening failed.";
202 QDataStream stream(&buffer);
203 stream << filterOutComplexTypes(map);
206 return buffer.data();
209 QVariantMap BlobIOHandler::byteArrayToVariantMap(
const QByteArray &array)
211 QByteArray nonConst = array;
212 QBuffer buffer(&nonConst);
213 if (!buffer.open(QIODevice::ReadOnly))
214 BLAME() <<
"Buffer opening failed.";
217 QDataStream stream(&buffer);
225 QVector<QByteArray> BlobIOHandler::pageByteArray(
const QByteArray &array)
227 QVector<QByteArray> dataPages;
228 QByteArray ba = array;
229 QBuffer pagingBuffer(&ba);
231 if (!pagingBuffer.open(QIODevice::ReadOnly))
232 BLAME() <<
"Error while paging BLOB. Buffer opening failed.";
234 while (!pagingBuffer.atEnd()) {
235 QByteArray page = pagingBuffer.read(SIGNON_IPC_BUFFER_PAGE_SIZE);
236 dataPages.append(page);
238 pagingBuffer.close();
Error codes for ui interaction.