コード例 #1
0
        /// <summary>
        /// Parses a single line of an TZDB zone info file.
        /// </summary>
        /// <remarks>
        /// <para>
        /// TZDB files have a simple line based structure. Each line defines one item. Comments
        /// start with a hash or pound sign (#) and continue to the end of the line. Blank lines are
        /// ignored. Of the remaining there are four line types which are determined by the first
        /// keyword on the line.
        /// </para>
        /// <para>
        /// A line beginning with the keyword <c>Link</c> defines an alias between one time zone and
        /// another. Both time zones use the same definition but have different names.
        /// </para>
        /// <para>
        /// A line beginning with the keyword <c>Rule</c> defines a daylight savings time
        /// calculation rule.
        /// </para>
        /// <para>
        /// A line beginning with the keyword <c>Zone</c> defines a time zone.
        /// </para>
        /// <para>
        /// A line beginning with leading whitespace (an empty keyword) defines another part of the
        /// preceeding time zone. As many lines as necessary to define the time zone can be listed,
        /// but they must all be together and only the first line can have a name.
        /// </para>
        /// </remarks>
        /// <param name="line">The line to parse.</param>
        /// <param name="database">The database to fill.</param>
        /// <return>The zone name just parsed, if any - so that it can be passed into the next call.</return>
        private string ParseLine(string line, string previousZone, TzdbDatabase database)
        {
            // Trim end-of-line comments
            int index = line.IndexOf("#", StringComparison.Ordinal);

            if (index >= 0)
            {
                line = line.Substring(0, index);
            }
            line = line.TrimEnd();
            if (line.Length == 0)
            {
                // We can still continue with the previous zone
                return(previousZone);
            }

            // Okay, everything left in the line should be "real" now.
            var tokens  = Tokens.Tokenize(line);
            var keyword = NextString(tokens, "Keyword");

            switch (keyword)
            {
            case KeywordRule:
                database.AddRule(ParseRule(tokens));
                return(null);

            case KeywordLink:
                var alias = ParseLink(tokens);
                database.AddAlias(alias.Item1, alias.Item2);
                return(null);

            case KeywordZone:
                var name = NextString(tokens, "GetName");
                database.AddZone(ParseZone(name, tokens));
                return(name);

            default:
                if (string.IsNullOrEmpty(keyword))
                {
                    if (previousZone == null)
                    {
                        throw new InvalidDataException("Zone continuation provided with no previous zone line");
                    }
                    database.AddZone(ParseZone(previousZone, tokens));
                    return(previousZone);
                }
                else
                {
                    throw new InvalidDataException($"Unexpected zone database keyword: {keyword}");
                }
            }
        }
コード例 #2
0
        /// <summary>
        ///   Parses a single line of an TZDB zone info file.
        /// </summary>
        /// <remarks>
        ///   <para>
        ///     TZDB files have a simple line based structure. Each line defines one item. Comments
        ///     start with a hash or pound sign (#) and continue to the end of the line. Blank lines are
        ///     ignored. Of the remaining there are four line types which are determined by the first
        ///     keyword on the line.
        ///   </para>
        ///   <para>
        ///     A line beginning with the keyword <c>Link</c> defines an alias between one time zone and
        ///     another. Both time zones use the same definition but have different names.
        ///   </para>
        ///   <para>
        ///     A line beginning with the keyword <c>Rule</c> defines a daylight savings time
        ///     calculation rule.
        ///   </para>
        ///   <para>
        ///     A line beginning with the keyword <c>Zone</c> defines a time zone.
        ///   </para>
        ///   <para>
        ///     A line beginning with leading whitespace (an empty keyword) defines another part of the
        ///     preceeding time zone. As many lines as necessary to define the time zone can be listed,
        ///     but they must all be together and only the first line can have a name.
        ///   </para>
        /// </remarks>
        /// <param name="line">The line to parse.</param>
        /// <param name="database">The database to fill.</param>
        internal void ParseLine(string line, TzdbDatabase database)
        {
            int index = line.IndexOf("#", StringComparison.Ordinal);

            if (index == 0)
            {
                return;
            }
            if (index > 0)
            {
                line = line.Substring(0, index - 1);
            }
            line = line.TrimEnd();
            if (line.Length == 0)
            {
                return;
            }
            var tokens  = Tokens.Tokenize(line);
            var keyword = NextString(tokens, "Keyword");

            switch (keyword)
            {
            case KeywordRule:
                database.AddRule(ParseRule(tokens));
                break;

            case KeywordLink:
                database.AddAlias(ParseLink(tokens));
                break;

            case KeywordZone:
                var name      = NextString(tokens, "GetName");
                var namedZone = ParseZone(name, tokens);
                database.AddZone(namedZone);
                break;

            default:
                if (string.IsNullOrEmpty(keyword))
                {
                    var zone = ParseZone(string.Empty, tokens);
                    database.AddZone(zone);
                }
                else
                {
                    throw new InvalidDataException("Unexpected zone database keyword: " + keyword);
                }
                break;
            }
        }
コード例 #3
0
        /// <summary>
        /// Parses a single line of an TZDB zone info file.
        /// </summary>
        /// <remarks>
        /// <para>
        /// TZDB files have a simple line based structure. Each line defines one item. Comments
        /// start with a hash or pound sign (#) and continue to the end of the line. Blank lines are
        /// ignored. Of the remaining there are four line types which are determined by the first
        /// keyword on the line.
        /// </para>
        /// <para>
        /// A line beginning with the keyword <c>Link</c> defines an alias between one time zone and
        /// another. Both time zones use the same definition but have different names.
        /// </para>
        /// <para>
        /// A line beginning with the keyword <c>Rule</c> defines a daylight savings time
        /// calculation rule.
        /// </para>
        /// <para>
        /// A line beginning with the keyword <c>Zone</c> defines a time zone.
        /// </para>
        /// <para>
        /// A line beginning with leading whitespace (an empty keyword) defines another part of the
        /// preceeding time zone. As many lines as necessary to define the time zone can be listed,
        /// but they must all be together and only the first line can have a name.
        /// </para>
        /// </remarks>
        /// <param name="line">The line to parse.</param>
        /// <param name="database">The database to fill.</param>
        /// <return>The zone name just parsed, if any - so that it can be passed into the next call.</return>
        private string ParseLine(string line, string previousZone, TzdbDatabase database)
        {
            // Trim end-of-line comments
            int index = line.IndexOf("#", StringComparison.Ordinal);
            if (index >= 0)
            {
                line = line.Substring(0, index);
            }
            line = line.TrimEnd();
            if (line.Length == 0)
            {
                // We can still continue with the previous zone
                return previousZone;
            }

            // Okay, everything left in the line should be "real" now.
            var tokens = Tokens.Tokenize(line);
            var keyword = NextString(tokens, "Keyword");
            switch (keyword)
            {
                case KeywordRule:
                    database.AddRule(ParseRule(tokens));
                    return null;
                case KeywordLink:
                    var alias = ParseLink(tokens);
                    database.AddAlias(alias.Item1, alias.Item2);
                    return null;
                case KeywordZone:
                    var name = NextString(tokens, "GetName");
                    database.AddZone(ParseZone(name, tokens));
                    return name;
                default:
                    if (string.IsNullOrEmpty(keyword))
                    {
                        if (previousZone == null)
                        {
                            throw new InvalidDataException("Zone continuation provided with no previous zone line");
                        }
                        database.AddZone(ParseZone(previousZone, tokens));
                        return previousZone;
                    }
                    else
                    {
                        throw new InvalidDataException($"Unexpected zone database keyword: {keyword}");
                    }                    
            }
        }
コード例 #4
0
 /// <summary>
 /// Parses a single line of an TZDB zone info file.
 /// </summary>
 /// <remarks>
 /// <para>
 /// TZDB files have a simple line based structure. Each line defines one item. Comments
 /// start with a hash or pound sign (#) and continue to the end of the line. Blank lines are
 /// ignored. Of the remaining there are four line types which are determined by the first
 /// keyword on the line.
 /// </para>
 /// <para>
 /// A line beginning with the keyword <c>Link</c> defines an alias between one time zone and
 /// another. Both time zones use the same definition but have different names.
 /// </para>
 /// <para>
 /// A line beginning with the keyword <c>Rule</c> defines a daylight savings time
 /// calculation rule.
 /// </para>
 /// <para>
 /// A line beginning with the keyword <c>Zone</c> defines a time zone.
 /// </para>
 /// <para>
 /// A line beginning with leading whitespace (an empty keyword) defines another part of the
 /// preceeding time zone. As many lines as necessary to define the time zone can be listed,
 /// but they must all be together and only the first line can have a name.
 /// </para>
 /// </remarks>
 /// <param name="line">The line to parse.</param>
 /// <param name="database">The database to fill.</param>
 internal void ParseLine(string line, TzdbDatabase database)
 {
     int index = line.IndexOf("#", StringComparison.Ordinal);
     if (index == 0)
     {
         return;
     }
     if (index > 0)
     {
         line = line.Substring(0, index - 1);
     }
     line = line.TrimEnd();
     if (line.Length == 0)
     {
         return;
     }
     var tokens = Tokens.Tokenize(line);
     var keyword = NextString(tokens, "Keyword");
     switch (keyword)
     {
         case KeywordRule:
             database.AddRule(ParseRule(tokens));
             break;
         case KeywordLink:
             database.AddAlias(ParseLink(tokens));
             break;
         case KeywordZone:
             var name = NextString(tokens, "GetName");
             var namedZone = ParseZone(name, tokens);
             database.AddZone(namedZone);
             break;
         default:
             if (string.IsNullOrEmpty(keyword))
             {
                 var zone = ParseZone(string.Empty, tokens);
                 database.AddZone(zone);
             }
             else
             {
                 throw new InvalidDataException($"Unexpected zone database keyword: {keyword}");
             }
             break;
     }
 }