/// <summary> /// Returns the values of the map as continous range. At best as one range. /// </summary> /// <returns></returns> public ValueRanges GetContinousRanges() { ValueRanges result = new ValueRanges(); if (this.Count > 0) { List <Int64> values = new List <long>(this.Keys); values.Sort(); Int64 last = values[0]; Int64 offset = values[0]; for (int i = 1; i < values.Count; i++) { if (values[i] != last + 1) { if (last == offset) { result.Add(new ValueRange(offset, null)); } else { result.Add(new ValueRange(offset, last)); } offset = values[i]; } last = values[i]; } if (last == offset) { result.Add(new ValueRange(offset, null)); } else { result.Add(new ValueRange(offset, last)); } } return(result); }
public static ValueRanges DecodeRanges(ISymbolEnumerator symbols) { ValueRanges result = new ValueRanges(); Symbol startSymbol = symbols.NextNonEOLSymbol(); Symbol current = startSymbol; current.Expect(Symbol.OpenParentheses); while (current != Symbol.CloseParentheses) { Symbol value1Symbol = symbols.NextNonEOLSymbol(); if ((value1Symbol == Symbol.Size) && !result.IsSizeDeclaration) { result.IsSizeDeclaration = true; symbols.NextNonEOLSymbol().Expect(Symbol.OpenParentheses); continue; } // check for valid number Int64?value1 = DecodeNumber(value1Symbol); if (!value1.HasValue) { value1Symbol.Assert(false, "Invalid range declaration!"); } // process next symbol ValueRange range; current = symbols.NextNonEOLSymbol(); if (current == Symbol.DoubleDot) { // its a continous range Symbol value2Symbol = symbols.NextNonEOLSymbol(); Int64? value2 = DecodeNumber(value2Symbol); value2Symbol.Assert(value2.HasValue && (value2.Value >= value1.Value), "Invalid range declaration!"); if (value2.Value == value1.Value) { range = new ValueRange(value1.Value, null); } else { range = new ValueRange(value1.Value, value2.Value); } current = symbols.NextNonEOLSymbol(); } else { // its a single number range = new ValueRange(value1.Value, null); } // validate range if (result.IsSizeDeclaration) { value1Symbol.Assert(range.Start >= 0, "Invalid range declaration! Size must be greater than 0"); } result.Add(range); // check next symbol current.Expect(Symbol.Pipe, Symbol.CloseParentheses); } if (result.IsSizeDeclaration) { current = symbols.NextNonEOLSymbol(); current.Expect(Symbol.CloseParentheses); } // validate ranges in between for (int i = 0; i < result.Count; i++) { for (int k = i + 1; k < result.Count; k++) { startSymbol.Assert(!result[i].IntersectsWith(result[k]), "Invalid range declaration! Overlapping of ranges!"); } } return(result); }