MI_Boolean mof_match()

in LCM/codec/mof/parser/utility.c [706:859]


MI_Boolean mof_match(MOF_Encoding e, _In_ MOF_StringLen *data, _In_ MOF_StringLen *pattern)
{
    unsigned char cset[256];
    MOF_Buffer d = {0}, p ={0};
    if (!(data->str.data) || !(pattern->str.data))
    {
        return MI_FALSE;
    }

    /* setup buffers for matching */
    {
        size_t ds = data->len * (e.u ? sizeof(wchar_t) : sizeof(char));
        size_t ps = pattern->len * (e.u ? sizeof(wchar_t) : sizeof(char));
        mof_setupbuffer_intl(data->str.data, ds, e, &d);
        mof_setupbuffer_intl(pattern->str.data, ps, e, &p);
    }

    while (mof_neof(&p))
    {
        int c = mof_getchar(p.e, p.cur);
        switch(c)
        {
        case '[':
            // a set, find ']', and read one more char, a char after ']' could be '*', '?', '+'
            // only support [x-ym-n] [xyz]
            {
                int c1, c2, c3;
                int ci;
                memset(cset, 0, 256*sizeof(unsigned char));
                c1 = mof_nextchar(&p);
                while(mof_neof(&p) && (c1 != ']'))
                {
                    c2 = mof_nextchar(&p);
                    if (isalnum(c1) && c2 == '-')
                    {
                        c3 = mof_nextchar(&p);
                        for (ci = c1; ci <= c3; ci++)
                        {
                            cset[ci] = 1;
                        }
                    }
                    else
                    {
                        _Analysis_assume_(c1 < 256);
                        _Analysis_assume_(c2 < 256);
                        cset[c1] = cset[c2] = 1;
                    }
                    c1 = mof_nextchar(&p);
                }
                if (mof_eof(&p))
                {
                    return MI_FALSE;
                }
                c1 = mof_nextchar(&p);
                switch(c1)
                {
                case '*':// 0+ match
                    {
                        while(mof_neof(&d))
                        {
                            if (cset[mof_getchar(d.e, d.cur)] != 1)
                                break;
                            mof_nextchar(&d);
                        }
                    }
                    mof_nextchar(&p);
                    break;
                case '+':// 1+ match
                    {
                        int dc;
                        if (mof_eof(&d))
                            return MI_FALSE;

                        // match first char
                        if (cset[mof_getchar(d.e, d.cur)] != 1)
                        {
                            return MI_FALSE;
                        }

                        dc = mof_nextchar(&d);
                        while(mof_neof(&d))
                        {
                            if (cset[dc] != 1)
                                break;
                            dc = mof_nextchar(&d);
                        }
                    }
                    mof_nextchar(&p);
                    break;
                case '?':// 0 or 1 match
                    {
                        if (mof_neof(&d))
                        {
                            if (cset[mof_getchar(d.e, d.cur)] == 1)
                            {
                                mof_nextchar(&d);
                            }
                        }
                    }
                    mof_nextchar(&p);
                    break;
                default: // 1 match
                    {
                        if (mof_eof(&d))
                            return MI_FALSE;

                        // have to match one char
                        if (cset[mof_getchar(d.e, d.cur)] != 1)
                        {
                            return MI_FALSE;
                        }
                        mof_nextchar(&d);
                    }
                    break;
                }
            }
            break;
        case '(':
            // only support '()?' pattern which at the end, for realvalue only
            {
                if (mof_neof(&d))
                {
                    MOF_StringLen d2;
                    MOF_StringLen p2;
                    d2.str.data = d.cur;
                    d2.len = data->len - mof_offset(d.e.u, data->str.data, d.cur);
                    mof_nextchar(&p);
                    p2.str.data = p.cur;
                    p2.len = pattern->len - mof_offset(p.e.u, pattern->str.data, p.cur) -2;
                    return mof_match(e, &d2, &p2);
                }
                else // in this case, it is matched
                {
                    return MI_TRUE;
                }
            }
            break;
        default:
            // single char match
            {
                if (mof_eof(&d))
                    return MI_FALSE;
                if (c != mof_getchar(d.e, d.cur))
                    return MI_FALSE;
                mof_nextchar(&d);
                mof_nextchar(&p);
            }
            break;
        }
    }

    if (mof_eof(&p) && mof_eof(&d)) return MI_TRUE;
    return MI_FALSE;
}