public override void GenerateFilterIl(ILGenerator generator, Dictionary<string, string> filterValues, PropertyInfo property)
        {
            Label lblReturnFalse = generator.DefineLabel();
            Label lblNextProperty = generator.DefineLabel();

            string minNumberString = filterValues["minNumber"];
            string maxNumberString = filterValues["maxNumber"];

            // If this is a nullable type such as bool?, the type is wrapped inside Nullable<> and we need to get the generic argument.
            string myPropertyType = IsNullable ?
                property.PropertyType.GetGenericArguments().Single().Name :
                property.PropertyType.Name;

            int storageIndex;

            switch (myPropertyType)
            {
                // Regardless of the width of the integer coming in, we treat it as a 64-bit integer.
                case "Byte":
                case "Int16":
                case "Int32":
                case "Int64":
                    if (myPropertyType == "Byte") storageIndex = nullableByteStorage;
                    else if (myPropertyType == "Int16") storageIndex = nullableInt16Storage;
                    else if (myPropertyType == "Int32") storageIndex = nullableInt32Storage;
                    else storageIndex = nullableInt64Storage;

                    if (!string.IsNullOrWhiteSpace(minNumberString))
                    {
                        generator.EmitCheckHasValue(property, storageIndex);
                        generator.Emit(OpCodes.Brfalse, lblReturnFalse); // return false if the property is null

                        // the integer from the record.
                        generator.EmitGetValueFromNullableProperty(property, storageIndex);
                        generator.Emit(OpCodes.Conv_I8); // convert to 64-bit integer
                        // the minimum integer
                        generator.Emit(OpCodes.Ldc_I8, Convert.ToInt64(minNumberString));
                        // If the integer is less than the minimum, return false.
                        generator.Emit(OpCodes.Blt, lblReturnFalse);
                    }
                    if (!string.IsNullOrWhiteSpace(maxNumberString))
                    {
                        generator.EmitCheckHasValue(property, storageIndex);
                        generator.Emit(OpCodes.Brfalse, lblReturnFalse); // return false if the property is null

                        // the integer from the record.
                        generator.EmitGetValueFromNullableProperty(property, storageIndex);
                        generator.Emit(OpCodes.Conv_I8); // convert to 64-bit integer
                        // the maximum integer
                        generator.Emit(OpCodes.Ldc_I8, Convert.ToInt64(maxNumberString));
                        // If the integer is greater than the maximum, return false.
                        generator.Emit(OpCodes.Bgt, lblReturnFalse);
                    }
                    break;
                // Floating point types
                case "Single":
                case "Double":
                    if (myPropertyType == "Single") storageIndex = nullableSingleStorage;
                    else storageIndex = nullableDoubleStorage;
                    if (!string.IsNullOrWhiteSpace(minNumberString))
                    {
                        generator.EmitCheckHasValue(property, storageIndex);
                        generator.Emit(OpCodes.Brfalse, lblReturnFalse); // return false if the integer is false

                        // the number from the record.
                        generator.EmitGetValueFromNullableProperty(property, storageIndex);
                        generator.Emit(OpCodes.Conv_R8); // convert to 64-bit floating-point number

                        // the minimum number
                        generator.Emit(OpCodes.Ldc_R8, Convert.ToDouble(minNumberString));
                        // If the number is less than the minimum, return false.
                        generator.Emit(OpCodes.Blt, lblReturnFalse);
                    }
                    if (!string.IsNullOrWhiteSpace(maxNumberString))
                    {
                        generator.EmitCheckHasValue(property, storageIndex);
                        generator.Emit(OpCodes.Brfalse, lblReturnFalse); // return false if the integer is false

                        // the number from the record.
                        generator.EmitGetValueFromNullableProperty(property, storageIndex);
                        generator.Emit(OpCodes.Conv_R8); // convert to 64-bit floating-point number
                        // the maximum number
                        generator.Emit(OpCodes.Ldc_R8, Convert.ToDouble(maxNumberString));
                        // If the number is greater than the maximum, return false.
                        generator.Emit(OpCodes.Bgt, lblReturnFalse);
                    }
                    break;
                // TODO: DECIMAL type
            }
            generator.Emit(OpCodes.Br, lblNextProperty);

            generator.MarkLabel(lblReturnFalse);
            generator.EmitReturnFalse();

            generator.MarkLabel(lblNextProperty);
        }
Example #2
0
        public override void GenerateFilterIl(System.Reflection.Emit.ILGenerator generator, Dictionary <string, string> filterValues, PropertyInfo property)
        {
            string minDateString = filterValues["minDate"];
            string maxDateString = filterValues["maxDate"];

            bool isNullable = property.PropertyType.Name == "Nullable`1";

            Label lblNextProperty = generator.DefineLabel();
            Label lblReturnFalse  = generator.DefineLabel();

            // First, get the value loaded, but if it is null, then return false unless both minDate and maxDate are blank.
            if (isNullable)
            {
                // This block of code is so-far UNTESTED!!!

                MethodInfo GetNullableHasValue = typeof(DateTime?).GetProperty("HasValue").GetGetMethod();
                MethodInfo GetNullableValue    = typeof(DateTime?).GetProperty("Value").GetGetMethod();

                bool  minAndMaxBothBlank = string.IsNullOrWhiteSpace(minDateString) && string.IsNullOrWhiteSpace(maxDateString);
                Label whereToGoIfNull    = minAndMaxBothBlank ? lblNextProperty : lblReturnFalse;

                // If the property is null and both min and max date are blank, then go to the next property.
                // If the property is null and either min or max date has a value, return false.
                generator.EmitGetPropertyValueFromArgument(property);
                generator.Emit(OpCodes.Stloc, nullableDateTimeStorage);
                generator.Emit(OpCodes.Ldloca_S, nullableDateTimeStorage);
                generator.Emit(OpCodes.Call, GetNullableHasValue);
                generator.Emit(OpCodes.Brfalse_S, whereToGoIfNull);
                // If we haven't jumped, then the datetime is not null, so just save it.
                generator.Emit(OpCodes.Ldloca_S, nullableDateTimeStorage);
                generator.Emit(OpCodes.Call, GetNullableValue);
                generator.Emit(OpCodes.Stloc, dateTimeStorage);
            }
            else // not nullable
            {
                // The property is not nullable, so just save the value.
                generator.EmitGetPropertyValueFromArgument(property);
                generator.Emit(OpCodes.Stloc, dateTimeStorage);
            }
            // At this point, the record's datetime should be saved in memory.
            MethodInfo DateTimeParse              = typeof(DateTime).GetMethod("Parse", new Type[] { typeof(string) });
            MethodInfo DateTimeLessThanOrEqual    = typeof(DateTime).GetMethod("op_LessThanOrEqual");
            MethodInfo DateTimeGreaterThanOrEqual = typeof(DateTime).GetMethod("op_GreaterThanOrEqual");

            if (!string.IsNullOrWhiteSpace(minDateString))
            {
                generator.Emit(OpCodes.Ldstr, minDateString);
                generator.Emit(OpCodes.Call, DateTimeParse);    // Get the mindate DateTime.
                generator.Emit(OpCodes.Ldloc, dateTimeStorage); // Get the record's DateTime from memory
                generator.Emit(OpCodes.Call, DateTimeLessThanOrEqual);
                generator.Emit(OpCodes.Brfalse, lblReturnFalse);
            }
            if (!string.IsNullOrWhiteSpace(maxDateString))
            {
                generator.Emit(OpCodes.Ldstr, maxDateString);
                generator.Emit(OpCodes.Call, DateTimeParse);    // Get the maxdate DateTime.
                generator.Emit(OpCodes.Ldloc, dateTimeStorage); // Get the record's DateTime from memory
                generator.Emit(OpCodes.Call, DateTimeGreaterThanOrEqual);
                generator.Emit(OpCodes.Brfalse, lblReturnFalse);
            }
            generator.Emit(OpCodes.Br, lblNextProperty);

            generator.MarkLabel(lblReturnFalse);
            generator.EmitReturnFalse();

            generator.MarkLabel(lblNextProperty);
        }
Example #3
0
        public override void GenerateFilterIl(System.Reflection.Emit.ILGenerator generator, Dictionary <string, string> filterValues, PropertyInfo property)
        {
            MethodInfo StringToLower            = typeof(string).GetMethod("ToLower", new Type[] { });
            MethodInfo StringStartsWith         = typeof(String).GetMethod("StartsWith", new Type[] { typeof(string) });
            MethodInfo StringContains           = typeof(String).GetMethod("Contains", new Type[] { typeof(string) });
            MethodInfo StringIsNullOrWhiteSpace = typeof(string).GetMethod("IsNullOrWhiteSpace", new Type[] { typeof(string) });

            Label lblNextProperty = generator.DefineLabel();
            Label lblNotNull      = generator.DefineLabel();

            string filterText = filterValues["filterText"];
            string filterMode = filterValues["filterMode"];

            // Do nothing for this property is the filterText is blank and the filterMode is "Starts With", "Doesn't Start With", "Contains", or " Doesn't Contain"
            if (string.IsNullOrWhiteSpace(filterText) && new string[] { "Starts With", "Doesn't Start With", "Contains", "Doesn't Contain" }.Contains(filterMode))
            {
                return;
            }

            switch (filterMode)
            {
            case "Starts With":
            case "Contains":
                // Check that the property is not null.  If it is null, return false; otherwise, continue.
                generator.EmitGetPropertyValueFromArgument(property);
                generator.Emit(OpCodes.Brtrue, lblNotNull);
                generator.EmitReturnFalse();
                generator.MarkLabel(lblNotNull);
                // Load the  property of the argument and make it lower-case.
                generator.EmitGetPropertyValueFromArgument(property);
                generator.Emit(OpCodes.Callvirt, StringToLower);
                // Load the lower-cased search key and see if the lower-cased property starts with it.
                generator.Emit(OpCodes.Ldstr, filterText.ToLower());
                // We use either String.StartsWith or String.Contains according to what the user specified.
                generator.Emit(OpCodes.Callvirt, filterMode == "Starts With" ? StringStartsWith : StringContains);
                // If the search key doesn't match, then return false; otherwise, go on to the next property
                generator.Emit(OpCodes.Brtrue, lblNextProperty);
                generator.EmitReturnFalse();
                break;

            case "Doesn't Start With":
            case "Doesn't Contain":
                // Check that the property is not null.  If it is null, then go on to the next property.
                generator.EmitGetPropertyValueFromArgument(property);
                generator.Emit(OpCodes.Brfalse, lblNextProperty);
                // Load the property of the argument and make it lower-case.
                generator.EmitGetPropertyValueFromArgument(property);
                generator.Emit(OpCodes.Callvirt, StringToLower);
                // Load the lower-cased search key and see if the lower-cased property starts with it.
                generator.Emit(OpCodes.Ldstr, filterText.ToLower());
                // We use either String.StartsWith or String.Contains according to what the user specified.
                generator.Emit(OpCodes.Callvirt, filterMode == "Starts With" ? StringStartsWith : StringContains);
                // Since we're doing the opposite of the "Starts With" and "Contains" cases, go to the next property
                // if the search key doesn't match, and return false otherwise.
                generator.Emit(OpCodes.Brfalse, lblNextProperty);
                generator.EmitReturnFalse();
                break;

            case "Is Blank":
                // Load the  property of the argument and see if it's null or whitespace
                generator.EmitGetPropertyValueFromArgument(property);
                generator.Emit(OpCodes.Call, StringIsNullOrWhiteSpace);
                // If we didn't get back true, then return false; otherwise, go on to the next property.
                generator.Emit(OpCodes.Brtrue, lblNextProperty);
                generator.EmitReturnFalse();
                break;

            case "Isn't Blank":
                // Load the  property of the argument and see if it's null or whitespace
                generator.EmitGetPropertyValueFromArgument(property);
                generator.Emit(OpCodes.Call, StringIsNullOrWhiteSpace);
                // If we didn't get back false, then return false; otherwise, go on to the next property.
                generator.Emit(OpCodes.Brfalse, lblNextProperty);
                generator.EmitReturnFalse();
                break;
            }

            generator.MarkLabel(lblNextProperty);
        }
        public override void GenerateFilterIl(ILGenerator generator, Dictionary<string, string> filterValues, PropertyInfo property)
        {
            // Note: If the user specifies both true and false, we can skip this instance

            string selection = filterValues["selection"];
            string selectionLower = selection.ToLower();

            bool selectionContainsTrue = selectionLower.Contains("true");
            bool selectionContainsFalse = selectionLower.Contains("false");
            bool selectionContainsNull = selectionLower.Contains("null");

            Label lblReturnFalse = generator.DefineLabel();
            Label lblCheckNextProperty = generator.DefineLabel();

            generator.EmitCheckHasValue(property, nullableBoolStorage); // push 1 onto the stack if property has value; 0 if it is null.
            generator.Emit(OpCodes.Pop);

            // If the filter matches null, check if the value is null.
            if (selectionContainsNull)
            {
                generator.EmitCheckHasValue(property, nullableBoolStorage);
                generator.Emit(OpCodes.Brfalse, lblCheckNextProperty);
            }
            // If the property didn't match null and has no value, return false.
            generator.EmitCheckHasValue(property, nullableBoolStorage);
            generator.Emit(OpCodes.Brfalse, lblReturnFalse);

            // From here on out, we assume the property has a value.
            if (selectionContainsTrue)
            {
                generator.EmitGetValueFromNullableProperty(property, nullableBoolStorage);
                generator.Emit(OpCodes.Brtrue, lblCheckNextProperty);
            }
            if (selectionContainsFalse)
            {
                generator.EmitGetValueFromNullableProperty(property, nullableBoolStorage);
                generator.Emit(OpCodes.Brfalse, lblCheckNextProperty);
            }

            // If we've gotten this far without finding one of the values the user passed in, the record doesn't match, so return false.
            generator.MarkLabel(lblReturnFalse);
            generator.EmitReturnFalse();

            generator.MarkLabel(lblCheckNextProperty);
        }