bool DInstance::DynamicToStatic()

in Unix/micxx/dinstance.cpp [852:1610]


bool DInstance::DynamicToStatic(
    const DInstance& dinst,
    bool keysOnly,
    bool ignoreUnknownProperties,
    Instance& sinst)
{
    if (!sinst.m_instance)
    {
        return false;
    }

    const MI_ClassDecl* cd = sinst.m_instance->classDecl;

    if (!cd)
    {
        return false;
    }

    // Get the property count.
    Uint32 count;
    
    if (MI_Instance_GetElementCount(dinst.m_self, &count) != MI_RESULT_OK)
    {
        return false;
    }

    // For each property in the dynamic instance.
    for (Uint32 i = 0; i < count; i++)
    {
        const MI_Char* name = NULL;
        MI_Value value;
        MI_Type type;
        MI_Uint32 flags;

        // Get the i-th property.
        if (MI_Instance_GetElementAt(
            dinst.m_self, i, &name, &value, &type, &flags) != MI_RESULT_OK)
        {
            return false;
        }

        // Find the index of the property with same name in target instance.
        MI_PropertyDecl* pd;
        {
            MI_Uint32 index = _FindPropertyDecl(cd, name);

            if (index == (MI_Uint32)-1)
            {
                if (ignoreUnknownProperties)
                    continue;

                return false;
            }

            pd = cd->properties[index];
        }

        // Get offset to field:
        size_t off = pd->offset;

        // Skip non-key properties if so requested.
        if (!(pd->flags & MI_FLAG_KEY) && keysOnly)
        {
            continue;
        }

        // Set the property in the target instanced.
        if (type == (MI_Type)pd->type)
        {
            if (flags & MI_FLAG_NULL)
            {
                switch (type)
                {
                    case MI_BOOLEAN:
                    {
                        sinst.GetField<Boolean>(off).Clear();
                        break;
                    }
                    case MI_BOOLEANA:
                        sinst.GetField<BooleanA>(off).Clear();
                        break;
                    case MI_UINT8:
                        sinst.GetField<Uint8>(off).Clear();
                        break;
                    case MI_UINT8A:
                        sinst.GetField<Uint8A>(off).Clear();
                        break;
                    case MI_SINT8:
                        sinst.GetField<Sint8>(off).Clear();
                        break;
                    case MI_SINT8A:
                        sinst.GetField<Sint8A>(off).Clear();
                        break;
                    case MI_UINT16:
                        sinst.GetField<Uint16>(off).Clear();
                        break;
                    case MI_UINT16A:
                        sinst.GetField<Uint16A>(off).Clear();
                        break;
                    case MI_SINT16:
                        sinst.GetField<Sint16>(off).Clear();
                        break;
                    case MI_SINT16A:
                        sinst.GetField<Sint16A>(off).Clear();
                        break;
                    case MI_UINT32:
                        sinst.GetField<Uint32>(off).Clear();
                        break;
                    case MI_UINT32A:
                        sinst.GetField<Uint32A>(off).Clear();
                        break;
                    case MI_SINT32:
                        sinst.GetField<Sint32>(off).Clear();
                        break;
                    case MI_SINT32A:
                        sinst.GetField<Sint32A>(off).Clear();
                        break;
                    case MI_UINT64:
                        sinst.GetField<Uint64>(off).Clear();
                        break;
                    case MI_UINT64A:
                        sinst.GetField<Uint64A>(off).Clear();
                        break;
                    case MI_SINT64:
                        sinst.GetField<Sint64>(off).Clear();
                        break;
                    case MI_SINT64A:
                        sinst.GetField<Sint64A>(off).Clear();
                        break;
                    case MI_REAL32:
                        sinst.GetField<Real32>(off).Clear();
                        break;
                    case MI_REAL32A:
                        sinst.GetField<Real32A>(off).Clear();
                        break;
                    case MI_REAL64:
                        sinst.GetField<Real64>(off).Clear();
                        break;
                    case MI_REAL64A:
                        sinst.GetField<Real64A>(off).Clear();
                        break;
                    case MI_CHAR16:
                        sinst.GetField<Char16>(off).Clear();
                        break;
                    case MI_CHAR16A:
                        sinst.GetField<Char16A>(off).Clear();
                        break;
                    case MI_DATETIME:
                        sinst.GetField<Datetime>(off).Clear();
                        break;
                    case MI_DATETIMEA:
                        sinst.GetField<DatetimeA>(off).Clear();
                        break;
                    case MI_STRING:
                        sinst.GetField<String>(off).Clear();
                        break;
                    case MI_STRINGA:
                        sinst.GetField<StringA>(off).Clear();
                        break;
                    case MI_REFERENCE:
                    case MI_INSTANCE:
                        sinst.GetField<Instance>(off).Clear();
                        break;
                    case MI_REFERENCEA:
                    case MI_INSTANCEA:
                        sinst.GetField<InstanceA>(off).Clear();
                        break;
                }
            }
            else
            {
                switch (type)
                {
                    case MI_BOOLEAN:
                        sinst.GetField<Uint8>(off).Set(value.uint8);
                        break;
                    case MI_UINT8:
                        sinst.GetField<Uint8>(off).Set(value.uint8);
                        break;
                    case MI_SINT8:
                        sinst.GetField<Sint8>(off).Set(value.sint8);
                        break;
                    case MI_UINT16:
                        sinst.GetField<Uint16>(off).Set(value.uint16);
                        break;
                    case MI_SINT16:
                        sinst.GetField<Sint16>(off).Set(value.sint16);
                        break;
                    case MI_UINT32:
                        sinst.GetField<Uint32>(off).Set(value.uint32);
                        break;
                    case MI_SINT32:
                        sinst.GetField<Sint32>(off).Set(value.sint32);
                        break;
                    case MI_UINT64:
                        sinst.GetField<Uint64>(off).Set(value.uint64);
                        break;
                    case MI_SINT64:
                        sinst.GetField<Sint64>(off).Set(value.sint64);
                        break;
                    case MI_REAL32:
                        sinst.GetField<Real32>(off).Set(value.real32);
                        break;
                    case MI_REAL64:
                        sinst.GetField<Real64>(off).Set(value.real64);
                        break;
                    case MI_CHAR16:
                        sinst.GetField<Char16>(off).Set(value.char16);
                        break;
                    case MI_DATETIME:
                        sinst.GetField<Datetime>(off).Set(value.datetime);
                        break;
                    case MI_STRING:
                        sinst.GetField<String>(off).Set(value.string);
                        break;
                    case MI_REFERENCE:
                    case MI_INSTANCE:
                    {
                        if (!value.instance)
                        {
                            return false;
                        }

                        const MI_ClassDecl* tcd = SchemaDecl_FindClassDecl(
                            cd->schema,  pd->className);

                        if (!tcd)
                        {
                            return false;
                        }

                        // ATTN: optimize: avoid cloning.
                        DInstance tdinst(value.instance, CLONE);
                        Instance x(tcd);

                        if (!DynamicToStatic(tdinst, keysOnly, 
                            ignoreUnknownProperties, x))
                        {
                            return false;
                        }

                        sinst.GetField<Instance>(off).Set(x);
                        break;
                    }
                    case MI_BOOLEANA:
                    {
                        BooleanA a(value.booleana.data, value.booleana.size);
                        sinst.GetField<BooleanA>(off).Set(a);
                        break;
                    }
                    case MI_UINT8A:
                    {
                        Uint8A a(value.uint8a.data, value.uint8a.size);
                        sinst.GetField<Uint8A>(off).Set(a);
                        break;
                    }
                    case MI_SINT8A:
                    {
                        Sint8A a(value.sint8a.data, value.sint8a.size);
                        sinst.GetField<Sint8A>(off).Set(a);
                        break;
                    }
                    case MI_UINT16A:
                    {
                        Uint16A a(value.uint16a.data, value.uint16a.size);
                        sinst.GetField<Uint16A>(off).Set(a);
                        break;
                    }
                    case MI_SINT16A:
                    {
                        Sint16A a(value.sint16a.data, value.sint16a.size);
                        sinst.GetField<Sint16A>(off).Set(a);
                        break;
                    }
                    case MI_UINT32A:
                    {
                        Uint32A a(value.uint32a.data, value.uint32a.size);
                        sinst.GetField<Uint32A>(off).Set(a);
                        break;
                    }
                    case MI_SINT32A:
                    {
                        Sint32A a(value.sint32a.data, value.sint32a.size);
                        sinst.GetField<Sint32A>(off).Set(a);
                        break;
                    }
                    case MI_UINT64A:
                    {
                        Uint64A a(value.uint64a.data, value.uint64a.size);
                        sinst.GetField<Uint64A>(off).Set(a);
                        break;
                    }
                    case MI_SINT64A:
                    {
                        Sint64A a(value.sint64a.data, value.sint64a.size);
                        sinst.GetField<Sint64A>(off).Set(a);
                        break;
                    }
                    case MI_REAL32A:
                    {
                        Real32A a(value.real32a.data, value.real32a.size);
                        sinst.GetField<Real32A>(off).Set(a);
                        break;
                    }
                    case MI_REAL64A:
                    {
                        Real64A a(value.real64a.data, value.real64a.size);
                        sinst.GetField<Real64A>(off).Set(a);
                        break;
                    }
                    case MI_CHAR16A:
                    {
                        Char16A a(value.char16a.data, value.char16a.size);
                        sinst.GetField<Char16A>(off).Set(a);
                        break;
                    }
                    case MI_DATETIMEA:
                    {
                        DatetimeA a(
                            reinterpret_cast<Datetime*>(value.datetimea.data), 
                            value.datetimea.size);
                        sinst.GetField<DatetimeA>(off).Set(a);
                        break;
                    }
                    case MI_STRINGA:
                    {
                        StringA a;

                        for (Uint32 j = 0; j < value.stringa.size; j++)
                            a.PushBack(String(value.stringa.data[j]));

                        sinst.GetField<StringA>(off).Set(a);
                        break;
                    }
                    case MI_REFERENCEA:
                    case MI_INSTANCEA:
                    {
                        if (!value.instancea.data)
                        {
                            return false;
                        }

                        const MI_ClassDecl* tcd = SchemaDecl_FindClassDecl(
                            cd->schema,  pd->className);

                        if (!tcd)
                        {
                            return false;
                        }

                        InstanceA a;

                        for (Uint32 j = 0; j < value.instancea.size; j++)
                        {
                            if (!value.instancea.data[j])
                            {
                                return false;
                            }

                            DInstance tdinst(value.instancea.data[j], CLONE);
                            Instance x(tcd);

                            if (!DynamicToStatic(tdinst, keysOnly, 
                                ignoreUnknownProperties, x))
                            {
                                return false;
                            }

                            a.PushBack(x);
                        }

                        sinst.GetField<InstanceA>(off).Set(a);
                        break;
                    }
                }
            }
        }
        else if (type == MI_STRING)
        {
            // Convert string to type of target property.
            switch (pd->type)
            {
                case MI_BOOLEAN:
                {
                    Boolean x;

                    if (StrToBoolean(value.string, &x) != 0)
                        return false;

                    sinst.GetField<Boolean>(off).Set(x);
                    break;
                }
                case MI_UINT8:
                {
                    Uint8 x;

                    if (StrToUint8(value.string, &x) != 0)
                        return false;

                    sinst.GetField<Uint8>(off).Set(x);
                    break;
                }
                case MI_SINT8:
                {
                    Sint8 x;

                    if (StrToSint8(value.string, &x) != 0)
                        return false;

                    sinst.GetField<Sint8>(off).Set(x);
                    break;
                }
                case MI_UINT16:
                {
                    Uint16 x;

                    if (StrToUint16(value.string, &x) != 0)
                        return false;

                    sinst.GetField<Uint16>(off).Set(x);
                    break;
                }
                case MI_SINT16:
                {
                    Sint16 x;

                    if (StrToSint16(value.string, &x) != 0)
                        return false;

                    sinst.GetField<Sint16>(off).Set(x);
                    break;
                }
                case MI_UINT32:
                {
                    Uint32 x;

                    if (StrToUint32(value.string, &x) != 0)
                        return false;

                    sinst.GetField<Uint32>(off).Set(x);
                    break;
                }
                case MI_SINT32:
                {
                    Sint32 x;

                    if (StrToSint32(value.string, &x) != 0)
                        return false;

                    sinst.GetField<Sint32>(off).Set(x);
                    break;
                }
                case MI_UINT64:
                {
                    Uint64 x;

                    if (StrToUint64(value.string, &x) != 0)
                        return false;

                    sinst.GetField<Uint64>(off).Set(x);
                    break;
                }
                case MI_SINT64:
                {
                    Sint64 x;

                    if (StrToSint64(value.string, &x) != 0)
                        return false;

                    sinst.GetField<Sint64>(off).Set(x);
                    break;
                }
                case MI_REAL32:
                {
                    Real32 x;

                    if (StrToReal32(value.string, &x) != 0)
                        return false;

                    sinst.GetField<Real32>(off).Set(x);
                    break;
                }
                case MI_REAL64:
                {
                    Real64 x;

                    if (StrToReal64(value.string, &x) != 0)
                        return false;

                    sinst.GetField<Real64>(off).Set(x);
                    break;
                }
                case MI_CHAR16:
                {
                    Char16 x;

                    if (StrToChar16(value.string, &x) != 0)
                        return false;

                    sinst.GetField<Char16>(off).Set(x);
                    break;
                }
                case MI_DATETIME:
                {
                    MI_Datetime x;

                    if (StrToDatetime(value.string, &x) != 0)
                        return false;

                    sinst.GetField<Datetime>(off).Set(Datetime(x));
                    break;
                }
                default:
                {
                    // Conversion to string to this type is unsupported!
                    return false;
                }
            }
        }
        else if (type == MI_STRINGA)
        {
            switch (pd->type)
            {
                case MI_BOOLEANA:
                {
                    Array<Boolean> a;

                    for (Uint32 j = 0; j < value.stringa.size; j++)
                    {
                        MI_Boolean x;

                        if (StrToBoolean(value.stringa.data[j], &x) != 0)
                            return false;

                        a.PushBack(x);
                    }

                    sinst.GetField<BooleanA>(off).Set(a);
                    break;
                }
                case MI_UINT8A:
                {
                    Array<Uint8> a;

                    for (Uint32 j = 0; j < value.stringa.size; j++)
                    {
                        MI_Uint8 x;

                        if (StrToUint8(value.stringa.data[j], &x) != 0)
                            return false;

                        a.PushBack(x);
                    }

                    sinst.GetField<Uint8A>(off).Set(a);
                    break;
                }
                case MI_SINT8A:
                {
                    Array<Sint8> a;

                    for (Uint32 j = 0; j < value.stringa.size; j++)
                    {
                        MI_Sint8 x;

                        if (StrToSint8(value.stringa.data[j], &x) != 0)
                            return false;

                        a.PushBack(x);
                    }

                    sinst.GetField<Sint8A>(off).Set(a);
                    break;
                }
                case MI_UINT16A:
                {
                    Array<Uint16> a;

                    for (Uint32 j = 0; j < value.stringa.size; j++)
                    {
                        MI_Uint16 x;

                        if (StrToUint16(value.stringa.data[j], &x) != 0)
                            return false;

                        a.PushBack(x);
                    }

                    sinst.GetField<Uint16A>(off).Set(a);
                    break;
                }
                case MI_SINT16A:
                {
                    Array<Sint16> a;

                    for (Uint32 j = 0; j < value.stringa.size; j++)
                    {
                        MI_Sint16 x;

                        if (StrToSint16(value.stringa.data[j], &x) != 0)
                            return false;

                        a.PushBack(x);
                    }

                    sinst.GetField<Sint16A>(off).Set(a);
                    break;
                }
                case MI_UINT32A:
                {
                    Array<Uint32> a;

                    for (Uint32 j = 0; j < value.stringa.size; j++)
                    {
                        MI_Uint32 x;

                        if (StrToUint32(value.stringa.data[j], &x) != 0)
                            return false;

                        a.PushBack(x);
                    }

                    sinst.GetField<Uint32A>(off).Set(a);
                    break;
                }
                case MI_SINT32A:
                {
                    Array<Sint32> a;

                    for (Uint32 j = 0; j < value.stringa.size; j++)
                    {
                        MI_Sint32 x;

                        if (StrToSint32(value.stringa.data[j], &x) != 0)
                            return false;

                        a.PushBack(x);
                    }

                    sinst.GetField<Sint32A>(off).Set(a);
                    break;
                }
                case MI_UINT64A:
                {
                    Array<Uint64> a;

                    for (Uint32 j = 0; j < value.stringa.size; j++)
                    {
                        MI_Uint64 x;

                        if (StrToUint64(value.stringa.data[j], &x) != 0)
                            return false;

                        a.PushBack(x);
                    }

                    sinst.GetField<Uint64A>(off).Set(a);
                    break;
                }
                case MI_SINT64A:
                {
                    Array<Sint64> a;

                    for (Uint32 j = 0; j < value.stringa.size; j++)
                    {
                        MI_Sint64 x;

                        if (StrToSint64(value.stringa.data[j], &x) != 0)
                            return false;

                        a.PushBack(x);
                    }

                    sinst.GetField<Sint64A>(off).Set(a);
                    break;
                }
                case MI_REAL32A:
                {
                    Array<Real32> a;

                    for (Uint32 j = 0; j < value.stringa.size; j++)
                    {
                        MI_Real32 x;

                        if (StrToReal32(value.stringa.data[j], &x) != 0)
                            return false;

                        a.PushBack(x);
                    }

                    sinst.GetField<Real32A>(off).Set(a);
                    break;
                }
                case MI_REAL64A:
                {
                    Array<Real64> a;

                    for (Uint32 j = 0; j < value.stringa.size; j++)
                    {
                        MI_Real64 x;

                        if (StrToReal64(value.stringa.data[j], &x) != 0)
                            return false;

                        a.PushBack(x);
                    }

                    sinst.GetField<Real64A>(off).Set(a);
                    break;
                }
                case MI_CHAR16A:
                {
                    Array<Char16> a;

                    for (Uint32 j = 0; j < value.stringa.size; j++)
                    {
                        MI_Char16 x;

                        if (StrToChar16(value.stringa.data[j], &x) != 0)
                            return false;

                        a.PushBack(x);
                    }

                    sinst.GetField<Char16A>(off).Set(a);
                    break;
                }
                case MI_DATETIMEA:
                {
                    Array<Datetime> a;

                    for (Uint32 j = 0; j < value.stringa.size; j++)
                    {
                        MI_Datetime x;

                        if (StrToDatetime(value.stringa.data[j], &x) != 0)
                            return false;

                        a.PushBack(x);
                    }

                    sinst.GetField<DatetimeA>(off).Set(a);
                    break;
                }
                default:
                {
                    // Conversion to string to this type is unsupported!
                    return false;
                }
            }
        }
        else
        {
            return false;
        }
    }

    return true;
}