mardi 29 juin 2021

Boost::spirit::qi extract parameters values from the line

I need to parse parameters values from the next line:

#EXT-X-KEY:METHOD=AES-128,URI="http://example.ru/123.key",IV=0x07a6ed33e15beca7f64e57e5137f7fde,KEYFORMAT="identity",KEYFORMATVERSIONS="1/2/3/4/5"

Parameters description:

METHOD (REQUIRED PARAMETER) could contain: NONE, AES-128, SAMPLE-AES values

URI (REQUIRED PARAMETER) is quoted string URL

IV (OPTIONAL PARAMETER) is hexadecimal-sequence, an unquoted string of characters from the set [0..9] and [A..F] that is prefixed with 0x or 0X. The length of IV is 32 symbols except of 0x prefix.

KEYFORMAT (OPTIONAL PARAMETER) is quoted string

KEYFORMATVERSIONS (OPTIONAL PARAMETER) is quoted string containing one or more positive integers separated by the "/" character (for example, "1", "1/2", or "1/2/5")

Also the order of the arguments is not important, i.e the line can take the following form

#EXT-X-KEY:URI="http://example.ru/123.key",IV=0x07a6ed33e15beca7f64e57e5137f7fde,METHOD=AES-128,KEYFORMAT="identity"

I wrote the following code to parse this line, but I'm newest in boost and I understand that this code unefficient, I didn't take into account all the requirements for the IV and KEYFORMATVERSIONS parameters. Also I don't know how to take into account the rule: "the order of the arguments is not important".

Should I inherit from qi::grammar, to wrote separate parser?

If you have any ideas how I can improve this code or how I can take into account all conditions please help me.

enum class KeyMethod {
    NONE,
    AES_128,
    SAMPLE_AES
};

struct KEY_METHOD_ : boost::spirit::qi::symbols<char, KeyMethod> {
    KEY_METHOD_() {
        add
            ("NONE", KeyMethod::NONE)
            ("AES-128", KeyMethod::AES_128)
            ("SAMPLE-AES", KeyMethod::SAMPLE_AES)
        ;
    }
};

// #EXT-X-KEY:<attribute-list>
bool PARSE_EXT_X_KEY(const std::string& line, ParserState& stateObj) {
    stateObj.isMediaPlaylist = true;

    namespace qi = boost::spirit::qi;
    KEY_METHOD_ keyMethod;

    KeyMethod method;
    std::string uri;
    std::string iv;
    std::string keyformat;
    std::string keyformatVersion;

    if (!qi::parse(begin(line), end(line),
        ( "#EXT-X-KEY:" >> 
        ("METHOD=" >> keyMethod) >> 
        (",URI=\"" >> +(qi::char_ - '"') >> '"') >>
        -(",IV=" >> (qi::string("0x") | qi::string("0X")) >> +(qi::char_ - ',')) >>
        -(",KEYFORMAT=\"" >> +(qi::alnum - '"') >> '"') >>
        -(",KEYFORMATVERSIONS=\"" >> +(qi::char_ - '"') >> '"') >>
        qi::eoi ), 
        method,
        uri,
        iv,
        keyformat,
        keyformatVersion)
    ) {
        return false;
    }

    return true;
}

Aucun commentaire:

Enregistrer un commentaire