Пример #1
0
bool Listener::processClientBuffer(Client &client)
{
    static const int headerSize = (sizeof(int) * 2);
    Console::main()->log(QString("processing %1").arg(client.commandBuffer.size()));
    if (client.commandBuffer.size() < headerSize) {
        return false;
    }

    int commandId, size;
    commandId = *(int*)client.commandBuffer.constData();
    size = *(int*)(client.commandBuffer.constData() + sizeof(int));

    if (size <= client.commandBuffer.size() - headerSize) {
        QByteArray data = client.commandBuffer.mid(headerSize, size);
        client.commandBuffer.remove(0, headerSize + size);

        switch (commandId) {
            case Commands::HandshakeCommand: {
                auto buffer = Akonadi::GetHandshake(data.constData());
                Console::main()->log(QString("    Handshake from %1").arg(buffer->name()->c_str()));
                sendCurrentRevision(client);
                break;
            }
            default:
                // client.hasSentCommand = true;
                break;
        }

        return client.commandBuffer.size() >= headerSize;
    } else {
        return false;
    }
}
Пример #2
0
void Listener::processCommand(int commandId, uint messageId, Client &client, uint size, const std::function<void()> &callback)
{
    switch (commandId) {
        case Akonadi2::Commands::HandshakeCommand: {
            flatbuffers::Verifier verifier((const uint8_t *)client.commandBuffer.constData(), size);
            if (Akonadi2::VerifyHandshakeBuffer(verifier)) {
                auto buffer = Akonadi2::GetHandshake(client.commandBuffer.constData());
                client.name = buffer->name()->c_str();
                sendCurrentRevision(client);
            } else {
                qWarning() << "received invalid command";
            }
            break;
        }
        case Akonadi2::Commands::SynchronizeCommand: {
            flatbuffers::Verifier verifier((const uint8_t *)client.commandBuffer.constData(), size);
            if (Akonadi2::VerifySynchronizeBuffer(verifier)) {
                auto buffer = Akonadi2::GetSynchronize(client.commandBuffer.constData());
                log(QString("\tSynchronize request (id %1) from %2").arg(messageId).arg(client.name));
                loadResource();
                if (!m_resource) {
                    qWarning() << "No resource loaded";
                    break;
                }
                //TODO a more elegant composition of jobs should be possible
                if (buffer->sourceSync()) {
                    bool localSync = buffer->localSync();
                    m_resource->synchronizeWithSource(m_pipeline).then<void>([callback, localSync, this](Async::Future<void> &f){
                        if (localSync) {
                            m_resource->processAllMessages().then<void>([callback](Async::Future<void> &f){
                                callback();
                                f.setFinished();
                            }).exec();
                        } else {
                            callback();
                            f.setFinished();
                        }
                    }).exec();
                } else if (buffer->localSync()) {
                    m_resource->processAllMessages().then<void>([callback](Async::Future<void> &f){
                        callback();
                        f.setFinished();
                    }).exec();
                }
                return;
            } else {
                qWarning() << "received invalid command";
            }
            break;
        }
        case Akonadi2::Commands::FetchEntityCommand:
        case Akonadi2::Commands::DeleteEntityCommand:
        case Akonadi2::Commands::ModifyEntityCommand:
        case Akonadi2::Commands::CreateEntityCommand:
            log(QString("\tCommand id %1 of type %2 from %3").arg(messageId).arg(commandId).arg(client.name));
            loadResource();
            if (m_resource) {
                m_resource->processCommand(commandId, client.commandBuffer, size, m_pipeline);
            }
            break;
        case Akonadi2::Commands::ShutdownCommand:
            log(QString("\tReceived shutdown command from %1").arg(client.name));
            callback();
            m_server->close();
            emit noClients();
            return;
        default:
            if (commandId > Akonadi2::Commands::CustomCommand) {
                loadResource();
                if (m_resource) {
                    m_resource->processCommand(commandId, client.commandBuffer, size, m_pipeline);
                }
            } else {
                //TODO: handle error: we don't know wtf this command is
            }
            break;
    }
    callback();
}