static MI_Boolean ArgsToInstance()

in Unix/cli/cli_c.c [209:527]


static MI_Boolean ArgsToInstance(
    const MI_Char*** _p,
    const MI_Char** end,
    MI_Uint32 metaType,
    MI_Boolean key,
    const MI_Char* methodName,
    MI_Instance **instanceOut)
{
    MI_Instance *instance;
    MI_Uint32 keyFlag = 0;
    const MI_Char **p = *_p;

    if (p == end)
        return MI_FALSE;

    // Consume opening brace:
    if (Tcscmp(*p++, MI_T("{")) != 0)
        return MI_FALSE;

    if (p == end)
        return MI_FALSE;


    if (metaType == MI_FLAG_METHOD)
    {
        if (Instance_NewDynamic(&instance, methodName, MI_FLAG_METHOD, NULL) != MI_RESULT_OK)
            return MI_FALSE;
    }
    else
    {
        if (Instance_NewDynamic(&instance, *p++, MI_FLAG_CLASS, NULL) != MI_RESULT_OK)
            return MI_FALSE;

        if (p == end)
        {
            MI_Instance_Delete(instance);
            return MI_FALSE;
        }
    }

    // Consume name/value pairs:
    for (;;)
    {
        if (key)
            keyFlag = MI_FLAG_KEY;

        const MI_Char *name;
        if (Tcscmp(*p, MI_T("}")) == 0)
        {
            p++;
            break;
        }

        // Get name:
        name = *p++;

        if (name[0] == '*' && name[1] != '\0')
        {
            name = &name[1];
            keyFlag = MI_FALSE;
        }

        if (p == end)
        {
            MI_Instance_Delete(instance);
            return MI_FALSE;
        }

        // Get value:
        if (Tcscmp(*p, MI_T("{")) == 0)
        {
            const MI_Char** q = FindClosingBrace(p);
            MI_Instance *tmpInst;
            MI_Value value;

            if (!q || q == end)
            {
                MI_Instance_Delete(instance);
                return MI_FALSE;
            }

            // Recursively call to obtain reference or embedded instance.

            if (!ArgsToInstance(&p, q, MI_FLAG_CLASS, key, NULL, &tmpInst))
            {
                MI_Instance_Delete(instance);
                return MI_FALSE;
            }

            value.instance = tmpInst;
            if (MI_Instance_AddElement(instance, name, &value, MI_INSTANCE, keyFlag | MI_FLAG_ADOPT) != MI_RESULT_OK)
                //!instance.AddInstance(name, tmpInst, MI_FALSE, key))
            {
                MI_Instance_Delete(tmpInst);
                MI_Instance_Delete(instance);
                return MI_FALSE;
            }
        }
        else if (Tcscmp(*p, MI_T("[")) == 0)
        {
            MI_Char** strArray = ZArr();
            PtrArray instanceArray;

            if (strArray == NULL)
            {
                MI_Instance_Delete(instance);
                return MI_FALSE;
            }
            if (PtrArray_Construct(&instanceArray, 5, _DeleteInstance) != 0)
            {
                ZArrFree(strArray);
                MI_Instance_Delete(instance);
                return MI_FALSE;
            }

            p++;

            // Find closing brace:
            while (*p && Tcscmp(*p, MI_T("]")) != 0)
            {
                if (Tcscmp(*p, MI_T("{")) == 0)
                {
                    const MI_Char** q = FindClosingBrace(p);
                    MI_Instance *tmpInst = NULL;

                    if (!q || q == end)
                    {
                        if (strArray)
                        {
#ifdef _PREFAST_
    #pragma prefast(push)
    #pragma prefast(disable:26018)
#endif
                            ZArrFree(strArray);
#ifdef _PREFAST_
    #pragma prefast(pop)
#endif
                        }
                        PtrArray_Destruct(&instanceArray);
                        MI_Instance_Delete(instance);
                        return MI_FALSE;
                    }

                    if (!ArgsToInstance(&p, q, MI_FLAG_CLASS, key, NULL, &tmpInst))
                    {
                        if (strArray)
                        {
#ifdef _PREFAST_
    #pragma prefast(push)
    #pragma prefast(disable:26018)
#endif
                            ZArrFree(strArray);
#ifdef _PREFAST_
    #pragma prefast(pop)
#endif
                        }
                        PtrArray_Destruct(&instanceArray);
                        MI_Instance_Delete(instance);
                        return MI_FALSE;
                    }
                    if (PtrArray_Append(&instanceArray, tmpInst) != 0)
                    {
                        if (strArray)
                        {
#ifdef _PREFAST_
    #pragma prefast(push)
    #pragma prefast(disable:26018)
#endif
                            ZArrFree(strArray);
#ifdef _PREFAST_
    #pragma prefast(pop)
#endif
                        }
                        PtrArray_Destruct(&instanceArray);
                        MI_Instance_Delete(instance);
                        MI_Instance_Delete(tmpInst);
                        return MI_FALSE;
                    }
                }
                else
                {
                    MI_Char **_strArray = strArray;
                    ZArrCat(&_strArray, *p++);
                    if (_strArray == NULL)
                    {
                        /* Failed */
                        if (strArray)
                        {
#ifdef _PREFAST_
    #pragma prefast(push)
    #pragma prefast(disable:26018)
#endif
                            ZArrFree(strArray);
#ifdef _PREFAST_
    #pragma prefast(pop)
#endif
                        }
                        PtrArray_Destruct(&instanceArray);
                        MI_Instance_Delete(instance);
                        return MI_FALSE;
                    }
                    strArray = _strArray;
                }
            }

            // Handle missing closing brace:
            if (p == end)
            {
                if (strArray)
                {
#ifdef _PREFAST_
    #pragma prefast(push)
    #pragma prefast(disable:26018)
#endif
                    ZArrFree(strArray);
#ifdef _PREFAST_
    #pragma prefast(pop)
#endif
                }
                PtrArray_Destruct(&instanceArray);
                MI_Instance_Delete(instance);
                return MI_FALSE;
            }

            if (instanceArray.size)
            {
                MI_Value value;
                MI_Uint32 flags = 0;
                value.instancea.data = (MI_Instance**) instanceArray.data;
                value.instancea.size = instanceArray.size;
                if (key)
                    flags = MI_FLAG_KEY;

                if (MI_Instance_AddElement(instance, name, &value, MI_INSTANCEA, flags) != MI_RESULT_OK)
                {
                    if (strArray)
                    {
#ifdef _PREFAST_
    #pragma prefast(push)
    #pragma prefast(disable:26018)
#endif
                        ZArrFree(strArray);
#ifdef _PREFAST_
    #pragma prefast(pop)
#endif
                    }
                    PtrArray_Destruct(&instanceArray);
                    MI_Instance_Delete(instance);
                    return MI_FALSE;
                }
            }
            else
            {
                MI_Uint32 arrLength = ZArrLen(strArray);
                if (arrLength)
                {
                    MI_Value value;
                    MI_Uint32 flags = 0;
                    value.stringa.data = strArray;
                    value.stringa.size = arrLength;
                    if (key)
                        flags = MI_FLAG_KEY;

                    if (MI_Instance_AddElement(instance, name, &value, MI_STRINGA, flags) != MI_RESULT_OK)
                    {
                        if (strArray)
                        {
#ifdef _PREFAST_
    #pragma prefast(push)
    #pragma prefast(disable:26018)
#endif
                            ZArrFree(strArray);
#ifdef _PREFAST_
    #pragma prefast(pop)
#endif
                        }
                        PtrArray_Destruct(&instanceArray);
                        MI_Instance_Delete(instance);
                        return MI_FALSE;
                    }
                }
            }

            if (strArray)
            {
#ifdef _PREFAST_
    #pragma prefast(push)
    #pragma prefast(disable:26018)
#endif
                ZArrFree(strArray);
#ifdef _PREFAST_
    #pragma prefast(pop)
#endif
            }
            PtrArray_Destruct(&instanceArray);
            p++;
        }
        else
        {
            MI_Value value;

            value.string = (MI_Char *)*p++;

            // Add property:
            if (MI_Instance_AddElement(instance, name, &value, MI_STRING, keyFlag | MI_FLAG_BORROW) != MI_RESULT_OK)
            {
                MI_Instance_Delete(instance);
                return MI_FALSE;
            }

            if (p == end)
                break;
        }
    }

    *_p = p;
    *instanceOut = instance;
    return MI_TRUE;
}