static bool TryGetYear(DateToken token, byte[] text, out int year) { int endIndex = token.StartIndex + token.Length; int index = token.StartIndex; year = 0; if (!token.IsNumeric) { return(false); } if (!ParseUtils.TryParseInt32(text, ref index, endIndex, out year)) { return(false); } if (year < 100) { year += (year < 70) ? 2000 : 1900; } if (year < 1969) { return(false); } return(true); }
static bool TryGetTimeZone(DateToken token, byte[] text, out int tzone) { tzone = 0; if (token.IsNumericZone) { if (!token.Flags.HasFlag(DateTokenFlags.HasSign)) { return(false); } int endIndex = token.StartIndex + token.Length; int index = token.StartIndex; int sign; if (text[index] == (byte)'-') { sign = -1; } else if (text[index] == (byte)'+') { sign = 1; } else { return(false); } index++; if (!ParseUtils.TryParseInt32(text, ref index, endIndex, out tzone) || index != endIndex) { return(false); } tzone *= sign; } else if (token.IsAlphaZone) { if (token.Length > 3) { return(false); } var name = Encoding.ASCII.GetString(text, token.StartIndex, token.Length); if (!timezones.TryGetValue(name, out tzone)) { return(false); } } else { return(false); } return(true); }
/// <summary> /// Tries to parse a version from a header such as Mime-Version. /// </summary> /// <remarks> /// Parses a MIME version string from the supplied buffer starting at the given index /// and spanning across the specified number of bytes. /// </remarks> /// <returns><c>true</c>, if the version was successfully parsed, <c>false</c> otherwise.</returns> /// <param name="buffer">The raw byte buffer to parse.</param> /// <param name="startIndex">The index into the buffer to start parsing.</param> /// <param name="length">The length of the buffer to parse.</param> /// <param name="version">The parsed version.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="buffer"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="startIndex"/> and <paramref name="length"/> do not specify /// a valid range in the byte array. /// </exception> public static bool TryParse(byte[] buffer, int startIndex, int length, out Version version) { ParseUtils.ValidateArguments(buffer, startIndex, length); var values = new List <int> (); int endIndex = startIndex + length; int index = startIndex; int value; version = null; do { if (!ParseUtils.SkipCommentsAndWhiteSpace(buffer, ref index, endIndex, false) || index >= endIndex) { return(false); } if (!ParseUtils.TryParseInt32(buffer, ref index, endIndex, out value)) { return(false); } values.Add(value); if (!ParseUtils.SkipCommentsAndWhiteSpace(buffer, ref index, endIndex, false)) { return(false); } if (index >= endIndex) { break; } if (buffer[index++] != (byte)'.') { return(false); } } while (index < endIndex); switch (values.Count) { case 4: version = new Version(values[0], values[1], values[2], values[3]); break; case 3: version = new Version(values[0], values[1], values[2]); break; case 2: version = new Version(values[0], values[1]); break; default: return(false); } return(true); }
static bool TryGetTimeOfDay(DateToken token, byte[] text, out int hour, out int minute, out int second) { int endIndex = token.StartIndex + token.Length; int index = token.StartIndex; hour = minute = second = 0; if (!token.IsTimeOfDay) { return(false); } if (!ParseUtils.TryParseInt32(text, ref index, endIndex, out hour) || hour > 23) { return(false); } if (index >= endIndex || text[index++] != (byte)':') { return(false); } if (!ParseUtils.TryParseInt32(text, ref index, endIndex, out minute) || minute > 59) { return(false); } // Allow just hh:mm (i.e. w/o the :ss?) if (index >= endIndex || text[index++] != (byte)':') { return(true); } if (!ParseUtils.TryParseInt32(text, ref index, endIndex, out second) || second > 59) { return(false); } if (index < endIndex) { return(false); } return(true); }
static bool TryGetDayOfMonth(DateToken token, byte[] text, out int day) { int endIndex = token.StartIndex + token.Length; int index = token.StartIndex; day = 0; if (!token.IsNumeric) { return(false); } if (!ParseUtils.TryParseInt32(text, ref index, endIndex, out day)) { return(false); } if (day <= 0 || day > 31) { return(false); } return(true); }
/// <summary> /// Tries to parse a version from a header such as Mime-Version. /// </summary> /// <returns><c>true</c>, if the version was successfully parsed, <c>false</c> otherwise.</returns> /// <param name="buffer">The raw byte buffer to parse.</param> /// <param name="startIndex">The index into the buffer to start parsing.</param> /// <param name="length">The length of the buffer to parse.</param> /// <param name="version">The parsed version.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="buffer"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="startIndex"/> and <paramref name="length"/> do not specify /// a valid range in the byte array. /// </exception> public static bool TryParseVersion(byte[] buffer, int startIndex, int length, out Version version) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (startIndex < 0 || startIndex > buffer.Length) { throw new ArgumentOutOfRangeException("startIndex"); } if (length < 0 || startIndex + length > buffer.Length) { throw new ArgumentOutOfRangeException("length"); } List <int> values = new List <int> (); int endIndex = startIndex + length; int index = startIndex; int value; version = null; do { if (!ParseUtils.SkipCommentsAndWhiteSpace(buffer, ref index, endIndex, false) || index >= endIndex) { return(false); } if (!ParseUtils.TryParseInt32(buffer, ref index, endIndex, out value)) { return(false); } values.Add(value); if (!ParseUtils.SkipCommentsAndWhiteSpace(buffer, ref index, endIndex, false)) { return(false); } if (index >= endIndex) { break; } if (buffer[index++] != (byte)'.') { return(false); } } while (index < endIndex); switch (values.Count) { case 4: version = new Version(values[0], values[1], values[2], values[3]); break; case 3: version = new Version(values[0], values[1], values[2]); break; case 2: version = new Version(values[0], values[1]); break; default: return(false); } return(true); }
static bool TryParseUnknownDateFormat(IList <DateToken> tokens, byte[] text, out DateTimeOffset date) { int? day = null, month = null, year = null, tzone = null; int hour = 0, minute = 0, second = 0; bool numericMonth = false; bool haveWeekday = false; bool haveTime = false; DayOfWeek weekday; TimeSpan offset; for (int i = 0; i < tokens.Count; i++) { int value; if (!haveWeekday && tokens[i].IsWeekday) { if (TryGetWeekday(tokens[i], text, out weekday)) { haveWeekday = true; continue; } } if ((month == null || numericMonth) && tokens[i].IsMonth) { if (TryGetMonth(tokens[i], text, out value)) { if (numericMonth) { numericMonth = false; day = month; } month = value; continue; } } if (!haveTime && tokens[i].IsTimeOfDay) { if (TryGetTimeOfDay(tokens[i], text, out hour, out minute, out second)) { haveTime = true; continue; } } if (tzone == null && tokens[i].IsTimeZone) { if (TryGetTimeZone(tokens[i], text, out value)) { tzone = value; continue; } } if (tokens[i].IsNumeric) { if (tokens[i].Length == 4) { if (year == null) { if (TryGetYear(tokens[i], text, out value)) { year = value; } } else if (tzone == null) { if (TryGetTimeZone(tokens[i], text, out value)) { tzone = value; } } continue; } if (tokens[i].Length > 2) { continue; } // Note: we likely have either YYYY[-/]MM[-/]DD or MM[-/]DD[-/]YY int endIndex = tokens[i].StartIndex + tokens[i].Length; int index = tokens[i].StartIndex; ParseUtils.TryParseInt32(text, ref index, endIndex, out value); if (month == null && value > 0 && value <= 12) { numericMonth = true; month = value; continue; } if (day == null && value > 0 && value <= 31) { day = value; continue; } if (year == null && value >= 69) { year = 1900 + value; continue; } } // WTF is this?? } if (year == null || month == null || day == null) { date = new DateTimeOffset(); return(false); } if (!haveTime) { hour = minute = second = 0; } if (tzone != null) { int minutes = tzone.Value % 100; int hours = tzone.Value / 100; offset = new TimeSpan(hours, minutes, 0); } else { offset = new TimeSpan(0); } try { date = new DateTimeOffset(year.Value, month.Value, day.Value, hour, minute, second, offset); } catch (ArgumentOutOfRangeException) { date = new DateTimeOffset(); return(false); } return(true); }