ActionResponse Service::onAction(const std::string& action, const xml::Document& doc)
{
    try
    {
        ActionResponse response(action, ServiceType::ConnectionManager);
        auto request = doc.getFirstChild();
    
        switch (actionFromString(action))
        {
        case Action::GetProtocolInfo:
            response.addArgument("Source",               getVariable(Variable::SourceProtocolInfo).getValue());
            response.addArgument("Sink",                 getVariable(Variable::SinkProtocolInfo).getValue());
            break;
        case Action::PrepareForConnection:
        {
            ConnectionInfo connInfo;
            connInfo.peerConnectionManager  = request.getChildNodeValue("PeerConnectionManager");
            connInfo.peerConnectionId       = std::stoi(request.getChildNodeValue("PeerConnectionID"));
            connInfo.direction              = directionFromString(request.getChildNodeValue("Direction"));
            
            ProtocolInfo protoInfo(request.getChildNodeValue("RemoteProtocolInfo"));;
            m_connectionManager.prepareForConnection(protoInfo, connInfo);
        
            response.addArgument("ConnectionID",         std::to_string(connInfo.connectionId));
            response.addArgument("AVTransportID",        std::to_string(connInfo.avTransportId));
            response.addArgument("RcsID",                std::to_string(connInfo.renderingControlServiceId));
            break;
        }
        case Action::ConnectionComplete:
            m_connectionManager.connectionComplete(std::stoi(request.getChildNodeValue("ConnectionID")));
            break;
        case Action::GetCurrentConnectionIDs:
            response.addArgument("ConnectionIDs",        getVariable(Variable::CurrentConnectionIds).getValue());
            break;
        case Action::GetCurrentConnectionInfo:
        {
            auto connInfo = m_connectionManager.getCurrentConnectionInfo(std::stoi(request.getChildNodeValue("ConnectionID")));
            response.addArgument("RcsID",                   std::to_string(connInfo.renderingControlServiceId));
            response.addArgument("AVTransportID",           std::to_string(connInfo.avTransportId));
            response.addArgument("ProtocolInfo",            connInfo.protocolInfo.toString());
            response.addArgument("PeerConnectionManager",   connInfo.peerConnectionManager);
            response.addArgument("PeerConnectionID",        std::to_string(connInfo.peerConnectionId));
            response.addArgument("Direction",               toString(connInfo.direction));
            response.addArgument("Status",                  toString(connInfo.connectionStatus));
            break;
        }
        default:
            throw InvalidActionException();
        }
        
        return response;
    }
    catch (std::exception& e)
    {
        log::error("Error processing ConnectionManager request: %s", e.what());
        throw InvalidActionException();
    }
}
示例#2
0
void APEditHandler::move(Direction direction)
{
    if (direction == Forward) current++;

    QString joinedActions = history[current];
    QStringList actions = joinedActions.split(ActionSeparator);

    foreach (QString serializedAction, actions) {
        QStringList tokens = serializedAction.split(InfoSeparator);
        EditAction action = actionFromString(tokens.first());
        QString info = tokens.last();

        EPSegment *segment;

        switch (action) {
        case Create: // info is just a serialized segment
        case Remove: {
            segment = EPSegment::unserialize(info);
            if ((direction == Forward && action == Create)
                    || (direction == Backward && action == Remove))
                profile->addSegment(segment, true);
            else
                profile->removeSegmentWithId(segment->id(), true);
            break;
        }

        case Update: { // info has format: id:property=prev-next
            QStringList idAndChange = info.split(":");
            int id = idAndChange.first().toInt();

            segment = profile->segmentWithId(id);
            if (!segment) {
                qCritical("APEditHandler::move() => no segment found for "
                          "requested id %i",
                          id);
            }
            segment->pushSerializedChange(idAndChange.last(), direction);
            break;
        }
        case None:
            break;
        }
    }
示例#3
0
Command *CommandParser::parse(const std::vector<std::string> &argv) {
    command_.clear();

    if (argv.begin() == argv.end()) {
        std::clog << "error: no command specified.\n"
                  "See 'irony-server help' to list available commands\n";
        return 0;
    }

    const std::string &actionStr = argv[0];

    command_.action = actionFromString(actionStr);

    bool handleUnsaved = false;
    bool readCompileOptions = false;
    std::vector<std::function<bool(const std::string &)>> positionalArgs;

    switch (command_.action) {
    case Command::SetDebug:
        positionalArgs.push_back(OptionConverter(&command_.opt));
        break;

    case Command::Parse:
        positionalArgs.push_back(StringConverter(&command_.file));
        handleUnsaved = true;
        readCompileOptions = true;
        break;

    case Command::Complete:
        positionalArgs.push_back(StringConverter(&command_.file));
        positionalArgs.push_back(UnsignedIntConverter(&command_.line));
        positionalArgs.push_back(UnsignedIntConverter(&command_.column));
        handleUnsaved = true;
        readCompileOptions = true;
        break;

    case Command::GetType:
        positionalArgs.push_back(UnsignedIntConverter(&command_.line));
        positionalArgs.push_back(UnsignedIntConverter(&command_.column));
        break;

    case Command::Diagnostics:
    case Command::Help:
    case Command::Exit:
        // no-arguments commands
        break;

    case Command::GetCompileOptions:
        positionalArgs.push_back(StringConverter(&command_.dir));
        positionalArgs.push_back(StringConverter(&command_.file));
        break;

    case Command::Unknown:
        std::clog << "error: invalid command specified: " << actionStr << "\n";
        return 0;
    }

    auto argIt = argv.begin() + 1;
    int argCount = std::distance(argIt, argv.end());

    // parse optional arguments come first
    while (argIt != argv.end()) {
        // '-' is allowed as a "default" file, this isn't an option but a positional
        // argument
        if ((*argIt)[0] != '-' || *argIt == "-")
            break;

        const std::string &opt = *argIt;

        ++argIt;
        argCount--;

        if (handleUnsaved) {
            // TODO: handle multiple unsaved files
            if (opt == "--num-unsaved=1") {
                command_.unsavedFiles.resize(1);
            }
        } else {
            std::clog << "error: invalid option for '" << actionStr << "': '" << opt
                      << "' unknown\n";
            return 0;
        }
    }

    if (argCount != static_cast<int>(positionalArgs.size())) {
        std::clog << "error: invalid number of arguments for '" << actionStr
                  << "' (requires " << positionalArgs.size() << " got " << argCount
                  << ")\n";
        return 0;
    }

    for (auto fn : positionalArgs) {
        if (!fn(*argIt)) {
            std::clog << "error: parsing command '" << actionStr
                      << "': invalid argument '" << *argIt << "'\n";
            return 0;
        }
        ++argIt;
    }

    // '-' is used as a special file to inform that the buffer hasn't been saved
    // on disk and only the buffer content is available. libclang needs a file, so
    // this is treated as a special value for irony-server to create a temporary
    // file for this. note taht libclang will gladly accept '-' as a filename but
    // we don't want to let this happen since irony already reads stdin.
    if (command_.file == "-") {
        command_.file = tempFile_.getPath();
    }

    // When a file is provided, the next line contains the compilation options to
    // pass to libclang.
    if (readCompileOptions) {
        std::string compileOptions;
        std::getline(std::cin, compileOptions);

        command_.flags = unescapeCommandLine(compileOptions);
    }

    // read unsaved files
    // filename
    // filesize
    // <file content...>
    for (auto &p : command_.unsavedFiles) {
        std::getline(std::cin, p.first);

        unsigned length;
        std::string filesizeStr;
        std::getline(std::cin, filesizeStr);

        UnsignedIntConverter uintConverter(&length);

        if (!uintConverter(filesizeStr)) {
            std::clog << "error: invalid file size '" << filesizeStr << "'\n";
            return 0;
        }

        p.second.resize(length);
        std::cin.read(p.second.data(), p.second.size());

        CXUnsavedFile cxUnsavedFile;

        cxUnsavedFile.Filename = p.first.c_str();
        cxUnsavedFile.Contents = p.second.data();
        cxUnsavedFile.Length = p.second.size();
        command_.cxUnsavedFiles.push_back(cxUnsavedFile);

        char nl;
        std::cin.read(&nl, 1);
        if (nl != '\n') {
            std::clog << "error: missing newline for unsaved file content\n";
            return 0;
        }
    }

    return &command_;
}