Пример #1
0
// Convert variant to data of given type. Error if the data types don't match
VIREO_FUNCTION_SIGNATURET(VariantToData, VariantToDataParamBlock)
{
    ErrorCluster *errPtr = _ParamPointer(ErrorClust);
    if (!errPtr || !errPtr->status) {
        TypeRef inputType = _ParamImmediate(InputData._paramType);
        void* inputData = _ParamImmediate(InputData)._pData;

        TypeRef targetType = _ParamPointer(TargetType);
        TypeRef outputType = _ParamImmediate(OutputData._paramType);
        void* outputData = _ParamImmediate(OutputData)._pData;

        if (targetType->IsStaticTypeWildcard() || (!outputType->IsStaticTypeAndDataWildcard() && !outputType->IsA(targetType, true))) {
            // In VIA, TargetType is a required argument. Generated VIA from G must guarantee this.
            // If TargetType is optional, just throw internal error and exit.
            // OutputData is optional. However, if supplied, outputType MUST be same as targetType. Generated VIA from G must guarantee this.
            // If violated, just throw internal error and exit.
            // We should not throw valid LV errors.
            if (errPtr)
                errPtr->SetErrorAndAppendCallChain(true, kUnspecifiedError, "Variant To Data");
            return _NextInstruction();
        }

        if (inputType->IsVariant()) {
            VariantTypeRef variant = *reinterpret_cast<VariantTypeRef *>_ParamImmediate(InputData._pData);
            if (VariantType::IsNullVariant(variant)) {
                if (errPtr)
                    errPtr->SetErrorAndAppendCallChain(true, kVariantIncompatibleType, "Variant To Data");
            } else {
                TypeRef underlyingType = variant->_underlyingTypeRef;
                if (targetType->IsVariant()) {
                    if (outputData)
                        *static_cast<VariantTypeRef *>(outputData) = VariantType::CreateNewVariantFromType(underlyingType);
                } else if (underlyingType->IsA(targetType, true)) {
                    if (outputData)
                        targetType->CopyData(underlyingType->Begin(kPARead), outputData);
                } else if (errPtr) {
                    VariantType::SetVariantToDataTypeError(underlyingType, targetType, outputType, outputData, errPtr);
                }
            }
        } else {