Commit bda86197 authored by Daniel Vrátil's avatar Daniel Vrátil 🤖

Start making it all compile :)

parent f02236bd
......@@ -62,7 +62,7 @@ void CollectionCreateJob::doStart()
Protocol::CreateCollectionCommand cmd;
cmd.setName(d->mCollection.name());
cmd.setParent(ProtocolHelper::entitySetToScope(Collection::List() << d->mCollection.parentCollection()));
cmd.setParent(ProtocolHelper::entityToScope(d->mCollection.parentCollection()));
cmd.setMimeTypes(d->mCollection.contentMimeTypes());
cmd.setRemoteId(d->mCollection.remoteId());
cmd.setRemoteRevision(d->mCollection.remoteRevision());
......@@ -94,16 +94,16 @@ void CollectionCreateJob::doHandleResponse(qint64 tag, const Protocol::Command &
Q_D(CollectionCreateJob);
if (!response.isResponse()) {
Job::doHandleResponse(tag, data);
Job::doHandleResponse(tag, response);
return;
}
if (response.type() == Protocol::Command::FetchCollections) {
Protocol::FetchCollectionsResponse resp(response);
d->mCollection = ProtocolHelper::parseCollection(resp);
if (!d->mCollection) {
if (!d->mCollection.isValid()) {
setError(Unknown);
setErrorText(i18n("Failed to parse Collection from response");
setErrorText(i18n("Failed to parse Collection from response"));
emitResult();
}
return;
......@@ -112,5 +112,5 @@ void CollectionCreateJob::doHandleResponse(qint64 tag, const Protocol::Command &
return;
}
Job::doHandleResponse(tag, data);
Job::doHandleResponse(tag, response);
}
......@@ -62,7 +62,7 @@ void CollectionDeleteJob::doStart()
return;
}
d->sendCommand(Protocol::DeleteCollectionCommand(ProtocolHelper::entitySetToScope({ d->mCollection })));
d->sendCommand(Protocol::DeleteCollectionCommand(ProtocolHelper::entityToScope(d->mCollection)));
}
void CollectionDeleteJob::doHandleResponse(qint64 tag, const Protocol::Command &response)
......
......@@ -99,7 +99,7 @@ public:
if (mBase.isValid()) {
return QStringLiteral("Collection Id %1").arg(mBase.id());
} else if (CollectionUtils::hasValidHierarchicalRID(mBase)) {
return QString::fromUtf8(QByteArray(QByteArray("(") + ProtocolHelper::hierarchicalRidToByteArray(mBase) + QByteArray(")")));
return QLatin1String("(") + ProtocolHelper::hierarchicalRidToScope(mBase).ridChain().join(QLatin1String(", ")) + QLatin1String(")");
} else {
return QString::fromLatin1("Collection RemoteId %1").arg(mBase.remoteId());
}
......@@ -304,7 +304,7 @@ void CollectionFetchJob::doHandleResponse(qint64 tag, const Protocol::Command &r
Protocol::FetchCollectionsResponse resp(response);
// Invalid response (no ID) means this was the last response
if (resp.id() = -1) {
if (resp.id() == -1) {
emitResult();
return;
}
......
......@@ -22,6 +22,8 @@
#include "job_p.h"
#include "protocolhelper_p.h"
#include <KLocalizedString>
#include <akonadi/private/protocol_p.h>
using namespace Akonadi;
......
......@@ -61,7 +61,7 @@ void CollectionSelectJob::doStart()
Q_D(CollectionSelectJob);
try {
d->sendCommand(ProtocolHelper::entityToScope(d->mCollection));
d->sendCommand(Protocol::SelectCollectionCommand(ProtocolHelper::entityToScope(d->mCollection)));
} catch (const std::exception &e) {
setError(Unknown);
setErrorText(QString::fromUtf8(e.what()));
......
......@@ -148,7 +148,10 @@ void ItemCreateJob::doHandleResponse(qint64 tag, const Protocol::Command &respon
if (streamCmd.destination().isEmpty()) {
streamResp.setData(d->mPendingData);
} else {
ProtocolHelper::streamPayloadToFile(streamCmd.destination(), d->mPendingData, error);
QByteArray error;
if (!ProtocolHelper::streamPayloadToFile(streamCmd.destination(), d->mPendingData, error)) {
// Error?
}
}
}
d->sendCommand(streamResp);
......
......@@ -41,42 +41,28 @@ using namespace Akonadi;
static QDBusAbstractInterface *s_jobtracker = 0;
//@cond PRIVATE
void JobPrivate::handleResponse(const QByteArray &tag, const QByteArray &data)
void JobPrivate::handleResponse(qint64 tag, const Protocol::Command &response)
{
Q_Q(Job);
if (mCurrentSubJob) {
mCurrentSubJob->d_ptr->handleResponse(tag, data);
mCurrentSubJob->d_ptr->handleResponse(tag, response);
return;
}
if (tag == mTag) {
if (data.startsWith("NO ") || data.startsWith("BAD ")) { //krazy:exclude=strings
QString msg = QString::fromUtf8(data);
msg.remove(0, msg.startsWith(QStringLiteral("NO ")) ? 3 : 4);
if (msg.endsWith(QStringLiteral("\r\n"))) {
msg.chop(2);
if (response.isResponse()) {
Protocol::Response resp(response);
if (resp.isError()) {
q->setError(Job::Unknown);
q->setErrorText(resp.errorMessage());
q->emitResult();
return;
}
q->setError(Job::Unknown);
q->setErrorText(msg);
q->emitResult();
return;
} else if (data.startsWith("OK")) { //krazy:exclude=strings
// We can't use emitResult() here: The slot connected to the result signal might exec()
// another job, and therefore this method would never return. That causes the session
// to deadlock, since it calls this method and does not continue starting new jobs until
// this method finishes. Which would also mean the exec()'d job is never started,, and there-
// fore everything deadlocks.
QTimer::singleShot(0, q, SLOT(delayedEmitResult()));
return;
}
}
q->doHandleResponse(tag, data);
q->doHandleResponse(tag, response);
}
void JobPrivate::init(QObject *parent)
......
......@@ -50,7 +50,7 @@ public:
void init(QObject *parent);
void handleResponse(const QByteArray &tag, const QByteArray &data);
void handleResponse(qint64 tag, const Protocol::Command &response);
void startQueued();
void lostConnection();
void slotSubJobAboutToStart(Akonadi::Job *job);
......
......@@ -78,7 +78,7 @@ void ProtocolHelper::parseAncestorsCached(const QVector<Protocol::Ancestor> &anc
entity->setParentCollection(pool->ancestorCollections.value(parentCollection));
} else {
// not cached yet, parse the chain
parseAncestors(data, entity);
parseAncestors(ancestors, entity);
pool->ancestorCollections.insert(parentCollection, entity->parentCollection());
}
}
......@@ -231,33 +231,6 @@ QByteArray ProtocolHelper::decodePartIdentifier(const QByteArray &data, PartName
}
}
Scope ProtocolHelper::entitySetToScope(const QList<Item> &_objects, const QByteArray &command)
{
if (_objects.isEmpty()) {
throw Exception("No objects specified");
}
Item::List objects(_objects);
std::sort(objects.begin(), objects.end(), boost::bind(&Item::id, _1) < boost::bind(&Item::id, _2));
if (objects.first().isValid()) {
// all items have a uid set
return entitySetToScope<Item>(objects, command);
}
// check if all items have a gid
if (std::find_if(objects.constBegin(), objects.constEnd(),
boost::bind(&QString::isEmpty, boost::bind(&Item::gid, _1)))
== objects.constEnd()) {
QStringList gids;
gids.reserve(objects.count());
for (const Item &object : objects) {
gids << object.gid();
}
return Scope(Scope::Gid, gids);
}
return entitySetToScope<Item>(objects, command);
}
Protocol::ScopeContext ProtocolHelper::commandContextToProtocol(const Akonadi::Collection &collection,
const Akonadi::Tag &tag,
const Item::List &requestedItems)
......@@ -302,10 +275,10 @@ Scope ProtocolHelper::hierarchicalRidToScope(const Collection &col)
Scope ProtocolHelper::hierarchicalRidToScope(const Item &item)
{
return Scope(Scope::HierarchicalRid, item.remoteId() + hierarchicalRidToScope(item.parentCollection()));
return Scope(Scope::HierarchicalRid, (QStringList() << item.remoteId()) + hierarchicalRidToScope(item.parentCollection()).ridChain());
}
Protocol::FetchScope ProtocolHelper::itemFetchScopeProtocol(const ItemFetchScope &fetchScope)
Protocol::FetchScope ProtocolHelper::itemFetchScopeToProtocol(const ItemFetchScope &fetchScope)
{
Protocol::FetchScope fs;
fs.setFetch(Protocol::FetchScope::FullPayload, fetchScope.fullPayload());
......@@ -336,7 +309,7 @@ Protocol::FetchScope ProtocolHelper::itemFetchScopeProtocol(const ItemFetchScope
fs.setFetch(Protocol::FetchScope::RemoteRevision, fetchScope.fetchRemoteIdentification());
fs.setFetch(Protocol::FetchScope::GID, fetchScope.fetchGid());
if (fetchScope.fetchTags()) {
fs.setFetch(Protocol::FetchScope::fetchTags());
fs.setFetch(Protocol::FetchScope::Tags);
if (!fetchScope.tagFetchScope().fetchIdOnly()) {
fs.setTagFetchScope(fetchScope.tagFetchScope().attributes());
}
......@@ -346,17 +319,17 @@ Protocol::FetchScope ProtocolHelper::itemFetchScopeProtocol(const ItemFetchScope
fs.setFetch(Protocol::FetchScope::MTime, fetchScope.fetchModificationTime());
fs.setFetch(Protocol::FetchScope::Relations, fetchScope.fetchRelations());
foreach (const QByteArray &part, fetchScope.payloadParts()) {
fs.setRequestedPayloads(QString::fromLatin1(ProtocolHelper::encodePartIdentifier(ProtocolHelper::PartPayload, part)));
for (const QByteArray &part : fetchScope.payloadParts()) {
fs.setRequestedPayloads({ ProtocolHelper::encodePartIdentifier(ProtocolHelper::PartPayload, part) });
}
foreach (const QByteArray &part, fetchScope.attributes()) {
fs.setRequestedParts(QString::fromLatin1(ProtocolHelper::encodePartIdentifier(ProtocolHelper::PartAttribute, part)));
for (const QByteArray &part : fetchScope.attributes()) {
fs.setRequestedParts({ ProtocolHelper::encodePartIdentifier(ProtocolHelper::PartAttribute, part) });
}
return fs;
}
static Item::Flags convertFlags(const QList<QByteArray> &flags, ProtocolHelperValuePool *valuePool)
static Item::Flags convertFlags(const QVector<QByteArray> &flags, ProtocolHelperValuePool *valuePool)
{
#if __cplusplus >= 201103L || defined(__GNUC__) || defined(__clang__)
// When the compiler supports thread-safe static initialization (mandated by the C++11 memory model)
......@@ -390,16 +363,16 @@ Item ProtocolHelper::parseItemFetchResult(const Protocol::FetchItemsResponse &da
item.setStorageCollectionId(data.parentId());
if (valuePool) {
item.setMimeType(valuePool->mimeTypePool.sharedValue(data.mimeType());
item.setMimeType(valuePool->mimeTypePool.sharedValue(data.mimeType()));
} else {
item.setMimeType(data.mimeType());
}
if (!item.isValid()) {
return;
return Item();
}
item.setFlag(convertFlags(data.flags(), valuePool));
item.setFlags(convertFlags(data.flags(), valuePool));
if (!data.tags().isEmpty()) {
Tag::List tags;
......@@ -441,20 +414,19 @@ Item ProtocolHelper::parseItemFetchResult(const Protocol::FetchItemsResponse &da
item.setModificationTime(data.MTime());
parseAncestorsCached(data.ancestors(), &item, data.parentId(), valuePool);
const auto parts = data.parts();
for (auto iter = parts.constBegin(), end = parts.constEnd(); iter != end; ++iter) {
for (const Protocol::StreamPayloadResponse &part : data.parts()) {
ProtocolHelper::PartNamespace ns;
const QByteArray plainKey = decodePartIdentifier(iter.key().name(), ns);
const QByteArray plainKey = decodePartIdentifier(part.payloadName(), ns);
switch (ns) {
case ProtocolHelper::PartPayload:
ItemSerializer::deserialize(item, plainKey, iter.value().data(), iter.key().version(), iter.value().isExternal());
ItemSerializer::deserialize(item, plainKey, part.data(), part.metaData().version(), part.metaData().isExternal());
break;
case ProtocolHelper::PartAttribute: {
Attribute *attr = AttributeFactory::createAttribute(plainKey);
Q_ASSERT(attr);
if (iter.value().isExternal()) {
const QString filename = ProtocolHelper::absolutePayloadFilePath(QString::fromUtf8(iter.value().data()));
QFile file(QString::fromUtf8(filename);
if (part.metaData().isExternal()) {
const QString filename = ProtocolHelper::absolutePayloadFilePath(QString::fromUtf8(part.data()));
QFile file(filename);
if (file.open(QFile::ReadOnly)) {
attr->deserialize(file.readAll());
} else {
......@@ -463,7 +435,7 @@ Item ProtocolHelper::parseItemFetchResult(const Protocol::FetchItemsResponse &da
attr = 0;
}
} else {
attr->deserialize(iter.value().data());
attr->deserialize(part.data());
}
if (attr) {
item.addAttribute(attr);
......@@ -472,20 +444,21 @@ Item ProtocolHelper::parseItemFetchResult(const Protocol::FetchItemsResponse &da
}
case ProtocolHelper::PartGlobal:
default:
qWarning() << "Unknown item part type:" << iter.key().name();
qWarning() << "Unknown item part type:" << part.payloadName();
}
}
item.d_ptr->resetChangeLog();
return item;
}
Tag ProtocolHelper::parseTagFetchResult(const Protocol::FetchTagsResponse &data)
{
Tag tag;
tag.setId(data.id());
tag.setGid(data.gid());
tag.setRemoteId(data.remoteId());
tag.setType(data.type());
tag.setGid(data.gid().toLatin1());
tag.setRemoteId(data.remoteId().toLatin1());
tag.setType(data.type().toLatin1());
parseAttributes(data.attributes(), &tag);
return tag;
......@@ -494,10 +467,10 @@ Tag ProtocolHelper::parseTagFetchResult(const Protocol::FetchTagsResponse &data)
Relation ProtocolHelper::parseRelationFetchResult(const Protocol::FetchRelationsResponse &data)
{
Relation relation;
relation.setLeft(data.left());
relation.setRight(data.right());
relation.setRemoteId(data.remoteId());
relation.setType(data.type());
relation.setLeft(Item(data.left()));
relation.setRight(Item(data.right()));
relation.setRemoteId(data.remoteId().toLatin1());
relation.setType(data.type().toLatin1());
return relation;
}
......@@ -520,22 +493,15 @@ QString ProtocolHelper::absolutePayloadFilePath(const QString &fileName)
return fileName;
}
bool ProtocolHelper::streamPayloadToFile(const QByteArray &command, const QByteArray &data, QByteArray &error)
bool ProtocolHelper::streamPayloadToFile(const QString &fileName, const QByteArray &data, QByteArray &error)
{
const int fnStart = command.indexOf("[FILE ") + 6;
if (fnStart == -1) {
qDebug() << "Unexpected response";
return false;
}
const int fnEnd = command.indexOf("]", fnStart);
const QByteArray fn = command.mid(fnStart, fnEnd - fnStart);
const QString fileName = ProtocolHelper::absolutePayloadFilePath(QString::fromLatin1(fn));
if (!fileName.startsWith(akonadiStoragePath())) {
const QString filePath = ProtocolHelper::absolutePayloadFilePath(fileName);
if (!filePath.startsWith(akonadiStoragePath())) {
qWarning() << "Invalid file path" << fileName;
error = "Invalid file path";
return false;
}
QFile file(fileName);
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
qWarning() << "Failed to open destination payload file" << file.errorString();
error = "Failed to store payload into file";
......
......@@ -90,7 +90,10 @@ public:
This method allows to pass a @p valuePool which acts as cache, so ancestor paths for the
same @p parentCollection don't have to be parsed twice.
*/
static void parseAncestorsCached(const QVector<Protocol::Ancestor> &ancestors, Entity *entity, Collection::Id parentCollection, ProtocolHelperValuePool *valuePool = 0, int start = 0);
static void parseAncestorsCached(const QVector<Protocol::Ancestor> &ancestors,
Entity *entity,
Collection::Id parentCollection,
ProtocolHelperValuePool *valuePool = 0);
/**
Parse a collection description.
......@@ -125,14 +128,14 @@ public:
Converts the given set of items into a protocol representation.
@throws A Akonadi::Exception if the item set contains items with missing/invalid identifiers.
*/
template <typename T>
static Scope entitySetToScope(const QVector<T> &_objects)
template<typename T, template<typename> class Container>
static Scope entitySetToScope(const Container<T> &_objects)
{
if (_objects.isEmpty()) {
throw Exception("No objects specified");
}
typename T::List objects(_objects);
Container<T> objects(_objects);
QByteArray rv;
std::sort(objects.begin(), objects.end(), boost::bind(&T::id, _1) < boost::bind(&T::id, _2));
......@@ -157,7 +160,7 @@ public:
// check if we have RIDs or HRIDs
if (std::find_if(objects.constBegin(), objects.constEnd(),
!boost::bind(static_cast<bool (*)(const T &)>(&CollectionUtils::hasValidHierarchicalRID), _1))
== objects.constEnd() && objects.size() == 1) { // ### HRID sets are not yet specified
== objects.constEnd() && objects.size() == 1) { // ### HRID sets are not yet specified
return hierarchicalRidToScope(objects.first());
}
......@@ -181,7 +184,7 @@ public:
template <typename T>
static Scope entityToScope(const T &object)
{
return entitySetToScope(typename T::List() << object);
return entitySetToScope(QVector<T>() << object);
}
/**
......@@ -216,9 +219,9 @@ public:
static QString akonadiStoragePath();
static QString absolutePayloadFilePath(const QString &fileName);
static bool streamPayloadToFile(const QByteArray &command, const QByteArray &data, QByteArray &error);
static bool streamPayloadToFile(const QString &file, const QByteArray &data, QByteArray &error);
Akonadi::Tristate listPreference(const Collection::ListPreference pref);
static Akonadi::Tristate listPreference(const Collection::ListPreference pref);
};
}
......
......@@ -239,7 +239,7 @@ ServerManager::State ServerManager::state()
// check if the server protocol is recent enough
if (sInstance.exists()) {
if (Internal::serverProtocolVersion() >= 0 &&
Internal::serverProtocolVersion() < SessionPrivate::minimumProtocolVersion()) {
Internal::serverProtocolVersion() < SessionPrivate::clientProtocolVersion()) {
return Broken;
}
}
......
......@@ -184,7 +184,7 @@ void SessionPrivate::dataReceived()
while (socket->bytesAvailable() > 0) {
QDataStream stream(socket);
qint64 tag;
// TODO: Verify the tag matches the last tag we send
// TODO: Verify the tag matches the last tag we sent
stream >> tag;
Protocol::Command cmd = Protocol::deserialize(socket);
......@@ -195,7 +195,7 @@ void SessionPrivate::dataReceived()
if (logFile) {
logFile->write("S: " + cmd.debugString());
logFile->write("S: " + cmd.debugString().toUtf8());
logFile->flush();
}
......@@ -205,7 +205,7 @@ void SessionPrivate::dataReceived()
if (hello.isError()) {
qWarning() << "Error when establishing connection with Akonadi server:" << hello.errorMessage();
socket->close();
QTimer::singleShot(1000, mParent, &Session::reconnect);
QTimer::singleShot(1000, mParent, SLOT(reconnect()));
break;
}
......@@ -216,7 +216,7 @@ void SessionPrivate::dataReceived()
protocolVersion = hello.protocolVersion();
Protocol::LoginCommand login(sessionId);
sendCommand(login);
sendCommand(nextTag(), login);
continue;
}
......@@ -226,7 +226,7 @@ void SessionPrivate::dataReceived()
if (login.isError()) {
qWarning() << "Unable to login to Akonadi server:" << login.errorMessage();
socket->close();
QTimer::singleShot(1000, mParent, &Session::reconnect);
QTimer::singleShot(1000, mParent, SLOT(reconnect()));
break;
}
......@@ -346,7 +346,7 @@ void SessionPrivate::addJob(Job *job)
startNext();
}
int SessionPrivate::nextTag()
qint64 SessionPrivate::nextTag()
{
return theNextTag++;
}
......@@ -354,7 +354,7 @@ int SessionPrivate::nextTag()
void SessionPrivate::sendCommand(qint64 tag, const Protocol::Command &command)
{
if (logFile) {
logFile->write("C: " + command.debugString());
logFile->write("C: " + command.debugString().toUtf8());
logFile->write("\n");
logFile->flush();
}
......
......@@ -102,7 +102,7 @@ public:
/**
Returns the next IMAP tag.
*/
int nextTag();
qint64 nextTag();
/**
Sends the given command to server
......@@ -128,7 +128,7 @@ public:
QByteArray sessionId;
QIODevice *socket;
bool connected;
int theNextTag;
qint64 theNextTag;
int protocolVersion;
// job management
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment