Ejemplo n.º 1
0
        private static void CompileExpression(IrGroup irGroup, ExpressionNode expression)
        {
            foreach (var arg in expression.Arguments)
            {
                switch (expression.ExpressionType)
                {
                case ExpressionType.Seconds:
                    CompileSecondsArgument(irGroup, arg);
                    break;

                case ExpressionType.Minutes:
                    CompileMinutesArgument(irGroup, arg);
                    break;

                case ExpressionType.Hours:
                    CompileHoursArgument(irGroup, arg);
                    break;

                case ExpressionType.DaysOfWeek:
                    CompileDaysOfWeekArgument(irGroup, arg);
                    break;

                case ExpressionType.DaysOfMonth:
                    CompileDaysOfMonthArgument(irGroup, arg);
                    break;

                case ExpressionType.Dates:
                    CompileDateArgument(irGroup, arg);
                    break;

                default:
                    throw new Exception("Expression type " + expression.ExpressionType + " not supported by the schyntax compiler." + SchyntaxException.PLEASE_REPORT_BUG_MSG);
                }
            }
        }
Ejemplo n.º 2
0
        private static void CompileDateArgument(IrGroup irGroup, ArgumentNode arg)
        {
            IrDate irStart;
            IrDate?irEnd   = null;
            var    isSplit = false;

            if (arg.IsWildcard)
            {
                irStart = new IrDate(null, 1, 1);
                irEnd   = new IrDate(null, 12, 31);
            }
            else
            {
                var start = (DateValueNode)arg.Range.Start;
                irStart = new IrDate(start.Year, start.Month, start.Day);

                if (arg.Range.End != null)
                {
                    var end = (DateValueNode)arg.Range.End;
                    irEnd = new IrDate(end.Year, end.Month, end.Day);
                }
                else if (arg.HasInterval)
                {
                    // if there is an interval, but no end value specified, then the end value is implied
                    irEnd = new IrDate(null, 12, 31);
                }

                // check for split range (spans January 1) - not applicable for dates with explicit years
                if (irEnd.HasValue && !start.Year.HasValue)
                {
                    if (irStart.Month >= irEnd.Value.Month &&
                        (irStart.Month > irEnd.Value.Month || irStart.Day > irEnd.Value.Day))
                    {
                        isSplit = true;
                    }
                }
            }

            var irArg = new IrDateRange(irStart, irEnd, arg.HasInterval ? arg.IntervalValue : 0, isSplit, arg.Range?.IsHalfOpen ?? false);

            (arg.IsExclusion ? irGroup.DatesExcluded : irGroup.Dates).Add(irArg);
        }
Ejemplo n.º 3
0
        private static void CompileDateArgument(IrGroup irGroup, ArgumentNode arg)
        {
            IrDate irStart;
            IrDate? irEnd = null;
            var isSplit = false;

            if (arg.IsWildcard)
            {
                irStart = new IrDate(null, 1, 1);
                irEnd = new IrDate(null, 12, 31);
            }
            else
            {
                var start = (DateValueNode)arg.Range.Start;
                irStart = new IrDate(start.Year, start.Month, start.Day);

                if (arg.Range.End != null)
                {
                    var end = (DateValueNode)arg.Range.End;
                    irEnd = new IrDate(end.Year, end.Month, end.Day);
                }
                else if (arg.HasInterval)
                {
                    // if there is an interval, but no end value specified, then the end value is implied
                    irEnd = new IrDate(null, 12, 31);
                }

                // check for split range (spans January 1) - not applicable for dates with explicit years
                if (irEnd.HasValue && !start.Year.HasValue)
                {
                    if (irStart.Month >= irEnd.Value.Month &&
                        (irStart.Month > irEnd.Value.Month || irStart.Day > irEnd.Value.Day))
                    {
                        isSplit = true;
                    }
                }
            }

            var irArg = new IrDateRange(irStart, irEnd, arg.HasInterval ? arg.IntervalValue : 0, isSplit, arg.Range?.IsHalfOpen ?? false);
            (arg.IsExclusion ? irGroup.DatesExcluded : irGroup.Dates).Add(irArg);
        }
Ejemplo n.º 4
0
        private static IrGroup CompileGroup(IReadOnlyList <ExpressionNode> expressions)
        {
            if (expressions == null || expressions.Count == 0)
            {
                return(null);
            }

            var irGroup = new IrGroup();

            foreach (var expression in expressions)
            {
                CompileExpression(irGroup, expression);
            }

            // setup implied rules
            if (irGroup.HasSeconds || irGroup.HasSecondsExcluded)
            {
                // don't need to setup any defaults if seconds are defined
            }
            else if (irGroup.HasMinutes || irGroup.HasMinutesExcluded)
            {
                irGroup.Seconds.Add(GetZeroInteger());
            }
            else if (irGroup.HasHours || irGroup.HasHoursExcluded)
            {
                irGroup.Seconds.Add(GetZeroInteger());
                irGroup.Minutes.Add(GetZeroInteger());
            }
            else // only a date level expression was set
            {
                irGroup.Seconds.Add(GetZeroInteger());
                irGroup.Minutes.Add(GetZeroInteger());
                irGroup.Hours.Add(GetZeroInteger());
            }

            return(irGroup);
        }
Ejemplo n.º 5
0
        private static void CompileDaysOfYearArgument(IrGroup irGroup, ArgumentNode arg)
        {
            var irArg = CompileIntegerArgument(arg, 1, 366);

            (arg.IsExclusion ? irGroup.DaysOfYearExcluded : irGroup.DaysOfYear).Add(irArg);
        }
Ejemplo n.º 6
0
        private static void CompileHoursArgument(IrGroup irGroup, ArgumentNode arg)
        {
            var irArg = CompileIntegerArgument(arg, 0, 23);

            (arg.IsExclusion ? irGroup.HoursExcluded : irGroup.Hours).Add(irArg);
        }
Ejemplo n.º 7
0
        private static void CompileMinutesArgument(IrGroup irGroup, ArgumentNode arg)
        {
            var irArg = CompileIntegerArgument(arg, 0, 59);

            (arg.IsExclusion ? irGroup.MinutesExcluded : irGroup.Minutes).Add(irArg);
        }
Ejemplo n.º 8
0
 private static void CompileExpression(IrGroup irGroup, ExpressionNode expression)
 {
     foreach (var arg in expression.Arguments)
     {
         switch (expression.ExpressionType)
         {
             case ExpressionType.Seconds:
                 CompileSecondsArgument(irGroup, arg);
                 break;
             case ExpressionType.Minutes:
                 CompileMinutesArgument(irGroup, arg);
                 break;
             case ExpressionType.Hours:
                 CompileHoursArgument(irGroup, arg);
                 break;
             case ExpressionType.DaysOfWeek:
                 CompileDaysOfWeekArgument(irGroup, arg);
                 break;
             case ExpressionType.DaysOfMonth:
                 CompileDaysOfMonthArgument(irGroup, arg);
                 break;
             case ExpressionType.DaysOfYear:
                 CompileDaysOfYearArgument(irGroup, arg);
                 break;
             case ExpressionType.Dates:
                 CompileDateArgument(irGroup, arg);
                 break;
             default:
                 throw new Exception("Expression type " + expression.ExpressionType + " not supported by the schyntax compiler." + SchyntaxException.PLEASE_REPORT_BUG_MSG);
         }
     }
 }
Ejemplo n.º 9
0
 private static void CompileDaysOfYearArgument(IrGroup irGroup, ArgumentNode arg)
 {
     var irArg = CompileIntegerArgument(arg, 1, 366);
     (arg.IsExclusion ? irGroup.DaysOfYearExcluded : irGroup.DaysOfYear).Add(irArg);
 }
Ejemplo n.º 10
0
 private static void CompileSecondsArgument(IrGroup irGroup, ArgumentNode arg)
 {
     var irArg = CompileIntegerArgument(arg, 0, 59);
     (arg.IsExclusion ? irGroup.SecondsExcluded : irGroup.Seconds).Add(irArg);
 }
Ejemplo n.º 11
0
 private static void CompileHoursArgument(IrGroup irGroup, ArgumentNode arg)
 {
     var irArg = CompileIntegerArgument(arg, 0, 23);
     (arg.IsExclusion ? irGroup.HoursExcluded : irGroup.Hours).Add(irArg);
 }
Ejemplo n.º 12
0
        private static IrGroup CompileGroup(IReadOnlyList<ExpressionNode> expressions)
        {
            if (expressions == null || expressions.Count == 0)
                return null;

            var irGroup = new IrGroup();

            foreach (var expression in expressions)
            {
                CompileExpression(irGroup, expression);
            }

            // setup implied rules
            if (irGroup.HasSeconds || irGroup.HasSecondsExcluded)
            {
                // don't need to setup any defaults if seconds are defined
            }
            else if (irGroup.HasMinutes || irGroup.HasMinutesExcluded)
            {
                irGroup.Seconds.Add(GetZeroInteger());
            }
            else if (irGroup.HasHours || irGroup.HasHoursExcluded)
            {
                irGroup.Seconds.Add(GetZeroInteger());
                irGroup.Minutes.Add(GetZeroInteger());
            }
            else // only a date level expression was set
            {
                irGroup.Seconds.Add(GetZeroInteger());
                irGroup.Minutes.Add(GetZeroInteger());
                irGroup.Hours.Add(GetZeroInteger());
            }

            return irGroup;
        }
Ejemplo n.º 13
0
        // yes yes, I know it's complicated, but settle down ReSharper
        // ReSharper disable once FunctionComplexityOverflow
        private static bool TryGetGroupEvent(IrGroup group, DateTimeOffset start, SearchMode mode, out DateTimeOffset result)
        {
            var after = mode == SearchMode.After;
            var inc = after ? 1 : -1; // used for incrementing values up or down depending on the direction we're searching

            var initHour = after ? 0 : 23;
            var initMinute = after ? 0 : 59;
            var initSecond = after ? 0 : 59;

            // todo: make the length of the search configurable
            for (var d = 0; d < 367; d++)
            {
                DateTimeOffset date;
                int hour, minute, second;
                if (d == 0)
                {
                    // "after" events must be in the future
                    date = after ? start.AddSeconds(1) : start;

                    hour = date.Hour;
                    minute = date.Minute;
                    second = date.Second;
                }
                else
                {
                    date = start.AddDays(d * inc);

                    hour = initHour;
                    minute = initMinute;
                    second = initSecond;
                }

                var year = date.Year;
                var month = date.Month;
                var dayOfWeek = (int)date.DayOfWeek + 1; // DayOfWeek enum is zero-indexed
                var dayOfMonth = date.Day;
                var daysInMonth = DateTime.DaysInMonth(year, month);

                // check if today is an applicable date
                if (group.HasDates)
                {
                    var applicable = false;
                    foreach (var range in group.Dates)
                    {
                        if (InDateRange(range, year, month, dayOfMonth))
                        {
                            applicable = true;
                            break;
                        }
                    }

                    if (!applicable)
                        goto CONTINUE_DATE_LOOP;
                }

                if (group.HasDatesExcluded)
                {
                    foreach (var range in group.DatesExcluded)
                    {
                        if (InDateRange(range, year, month, dayOfMonth))
                            goto CONTINUE_DATE_LOOP;
                    }
                }

                // check if date is an applicable day of month
                if (group.HasDaysOfMonth)
                {
                    var applicable = false;
                    foreach (var range in group.DaysOfMonth)
                    {
                        if (InDayOfMonthRange(range, year, month, dayOfMonth))
                        {
                            applicable = true;
                            break;
                        }
                    }

                    if (!applicable)
                        goto CONTINUE_DATE_LOOP;
                }

                if (group.HasDaysOfMonthExcluded)
                {
                    foreach (var range in group.DaysOfMonthExcluded)
                    {
                        if (InDayOfMonthRange(range, year, month, dayOfMonth))
                            goto CONTINUE_DATE_LOOP;
                    }
                }

                // check if date is an applicable day of week
                if (group.HasDaysOfWeek && !InRule(7, group.DaysOfWeek, dayOfWeek))
                    goto CONTINUE_DATE_LOOP;

                if (group.HasDaysOfWeekExcluded && InRule(7, group.DaysOfWeekExcluded, dayOfWeek))
                    goto CONTINUE_DATE_LOOP;

                // if we've gotten this far, then today is an applicable day, let's keep going with hour checks
                var hourCount = after ? 24 - hour : hour + 1;
                for (; hourCount-- > 0; hour += inc, minute = initMinute, second = initSecond)
                {
                    if (group.HasHours && !InRule(24, group.Hours, hour))
                        continue;

                    if (group.HasHoursExcluded && InRule(24, group.HoursExcluded, hour))
                        continue;

                    // if we've gotten here, the date and hour are valid. Let's check for minutes
                    var minuteCount = after ? 60 - minute : minute + 1;
                    for (; minuteCount-- > 0; minute += inc, second = initSecond)
                    {
                        if (group.HasMinutes && !InRule(60, group.Minutes, minute))
                            continue;

                        if (group.HasMinutesExcluded && InRule(60, group.MinutesExcluded, minute))
                            continue;

                        // check for valid seconds
                        var secondCount = after ? 60 - second : second + 1;
                        for (; secondCount-- > 0; second += inc)
                        {
                            if (group.HasSeconds && !InRule(60, group.Seconds, second))
                                continue;

                            if (group.HasSecondsExcluded && InRule(60, group.SecondsExcluded, second))
                                continue;

                            // we've found our event
                            result = new DateTimeOffset(year, month, dayOfMonth, hour, minute, second, TimeSpan.Zero);
                            return true;
                        }
                    }
                }

                CONTINUE_DATE_LOOP:;
            }

            // we didn't find an applicable date
            result = default(DateTimeOffset);
            return false;
        }