Optional Procedure::UpdateUserParameters()

in src/modules/compliance/src/lib/Procedure.cpp [101:185]


Optional<Error> Procedure::UpdateUserParameters(const std::string& input)
{
    size_t pos = 0;
    while (pos < input.size())
    {
        // Skip spaces
        pos = SkipSpaces(input, pos);
        if (pos >= input.size())
        {
            break;
        }

        // Parse key
        const size_t keyStart = pos;
        auto result = ParseKey(input, pos);
        if (!result.HasValue())
        {
            return result.Error();
        }
        pos = result.Value();
        if (keyStart == pos)
        {
            return Error("Invalid key-value pair: empty key");
        }

        auto key = input.substr(keyStart, pos - keyStart);
        if ((pos >= input.size()) || (input[pos] != '='))
        {
            return Error("Invalid key-value pair: '=' expected");
        }
        pos++; // Move past assignment character
        if (pos >= input.size() || isspace(input[pos]))
        {
            return Error("Invalid key-value pair: missing value");
        }

        // Parse value
        std::string value;
        if ((input[pos] == '"') || (input[pos] == '\''))
        {
            const size_t valueStart = pos;
            pos = ParseQuotedValue(input, pos, value);

            // Check if the pos points past a proper quote
            if (input[pos - 1] != input[valueStart])
            {
                return Error("Invalid key-value pair: missing closing quote or invalid escape sequence");
            }

            // If at the end of the input, we need to check if a closing quote was found, e.g.:
            // k1=" should fail (ParseQuotedValue will terminate at the opening quote and return valueStart+1)
            if ((pos >= input.size()) && (pos - valueStart == 1))
            {
                return Error("Invalid key-value pair: missing closing quote at the end of the input");
            }

            // We want to have at least one space after the value, e.g.:
            // k1="1"k2="v2" should fail
            if ((pos < input.size()) && (!isspace(input[pos])))
            {
                return Error("Invalid key-value pair: space expected after quoted value");
            }
        }
        else
        {
            // Unquoted value
            const size_t valueStart = pos;
            while (pos < input.size() && !isspace(input[pos]))
            {
                pos++;
            }
            value = input.substr(valueStart, pos - valueStart);
        }

        auto it = mParameters.find(key);
        if (it == mParameters.end())
        {
            return Error(std::string("User parameter '") + key + std::string("' not found"));
        }

        it->second = value;
    }

    return Optional<Error>();
}