Beispiel #1
0
 private static void LogWindowsZonesSummary(WindowsZones windowsZones)
 {
     Console.WriteLine("Windows Zones:");
     Console.WriteLine("  Version: {0}", windowsZones.Version);
     Console.WriteLine("  TZDB version: {0}", windowsZones.TzdbVersion);
     Console.WriteLine("  Windows version: {0}", windowsZones.WindowsVersion);
     Console.WriteLine("  {0} MapZones", windowsZones.MapZones.Count);
     Console.WriteLine("  {0} primary mappings", windowsZones.PrimaryMapping.Count);
 }
Beispiel #2
0
        public void MergeWindowsZones()
        {
            var originalZones = new WindowsZones("orig-version", "orig-tzdb-version", "orig-win-version",
                new[]
                {
                    new MapZone("ID1", "001", new[] { "A" }),
                    new MapZone("ID1", "T1-1", new[] { "B", "C" }),
                    new MapZone("ID1", "T1-2", new[] { "D" }),
                    new MapZone("ID2", "001", new[] { "E" }),
                    new MapZone("ID2", "T2-1", new[] { "F" })
                });

            var overrideZones = new WindowsZones("override-version", "", "",
                new[]
                {
                    // Replace ID1 / 001
                    new MapZone("ID1", "001", new[] { "A1" }),
                    // Delete ID1 / T1-1
                    new MapZone("ID1", "T1-1", new string[0]),
                    // (Leave ID1 / T1-2)
                    // Add ID1 / T1-3
                    new MapZone("ID1", "T1-3", new[] { "B1", "C1", "G1" }),
                    // (Leave ID2 / 001)
                    // Replace ID2 / T2-1
                    new MapZone("ID2", "T2-1", new[] { "H1" }),
                    // Add ID3 / 001
                    new MapZone("ID3", "001", new[] { "I1" })
                });
            var actual = Program.MergeWindowsZones(originalZones, overrideZones);
            var expected = new WindowsZones("override-version", "orig-tzdb-version", "orig-win-version",
                new[]
                {
                    new MapZone("ID1", "001", new[] { "A1" }),
                    new MapZone("ID1", "T1-2", new[] { "D" }),
                    new MapZone("ID1", "T1-3", new[] { "B1", "C1", "G1" }),
                    new MapZone("ID2", "001", new[] { "E" }),
                    new MapZone("ID2", "T2-1", new[] { "H1" }),
                    new MapZone("ID3", "001", new[] { "I1" })
                });

            // Could implement IEquatable<WindowsZones>, but it doesn't seem worth it right now.
            Assert.AreEqual(expected.Version, actual.Version);
            Assert.AreEqual(expected.TzdbVersion, actual.TzdbVersion);
            Assert.AreEqual(expected.WindowsVersion, actual.WindowsVersion);
            Assert.AreEqual(expected.MapZones, actual.MapZones);
        }
        public void Write(
            TzdbDatabase database,
            WindowsZones cldrWindowsZones,
            IDictionary<string, string> additionalWindowsNameToIdMappings,
            Stream stream)
        {
            FieldCollection fields = new FieldCollection();

            var zones = database.GenerateDateTimeZones().ToList();
            var stringPool = CreateOptimizedStringPool(zones, database.ZoneLocations, database.Zone1970Locations, cldrWindowsZones);
            
            // First assemble the fields (writing to the string pool as we go)
            foreach (var zone in zones)
            {
                var zoneField = fields.AddField(TzdbStreamFieldId.TimeZone, stringPool);
                WriteZone(zone, zoneField.Writer);
            }

            fields.AddField(TzdbStreamFieldId.TzdbVersion, null).Writer.WriteString(database.Version);

            // Normalize the aliases
            var timeZoneMap = new Dictionary<string, string>();
            foreach (var key in database.Aliases.Keys)
            {
                var value = database.Aliases[key];
                while (database.Aliases.ContainsKey(value))
                {
                    value = database.Aliases[value];
                }
                timeZoneMap.Add(key, value);
            }

            fields.AddField(TzdbStreamFieldId.TzdbIdMap, stringPool).Writer.WriteDictionary(timeZoneMap);

            // Windows mappings
            cldrWindowsZones.Write(fields.AddField(TzdbStreamFieldId.CldrSupplementalWindowsZones, stringPool).Writer);
            fields.AddField(TzdbStreamFieldId.WindowsAdditionalStandardNameToIdMapping, stringPool).Writer.WriteDictionary
                (additionalWindowsNameToIdMappings.ToDictionary(pair => pair.Key, pair => cldrWindowsZones.PrimaryMapping[pair.Value]));

            // Zone locations, if any.
            var zoneLocations = database.ZoneLocations;
            if (zoneLocations != null)
            {
                var field = fields.AddField(TzdbStreamFieldId.ZoneLocations, stringPool);
                field.Writer.WriteCount(zoneLocations.Count);
                foreach (var zoneLocation in zoneLocations)
                {
                    zoneLocation.Write(field.Writer);
                }
            }

            // Zone 1970 locations, if any.
            var zone1970Locations = database.Zone1970Locations;
            if (zone1970Locations != null)
            {
                var field = fields.AddField(TzdbStreamFieldId.Zone1970Locations, stringPool);
                field.Writer.WriteCount(zone1970Locations.Count);
                foreach (var zoneLocation in zone1970Locations)
                {
                    zoneLocation.Write(field.Writer);
                }
            }

            var stringPoolField = fields.AddField(TzdbStreamFieldId.StringPool, null);
            stringPoolField.Writer.WriteCount(stringPool.Count);
            foreach (string value in stringPool)
            {
                stringPoolField.Writer.WriteString(value);
            }

            // Now write all the fields out, in the right order.
            new BinaryWriter(stream).Write(Version);
            fields.WriteTo(stream);
        }
 /// <summary>
 /// Creates a string pool which contains the most commonly-used strings within the given set
 /// of zones first. This will allow them to be more efficiently represented when we write them out for real.
 /// </summary>
 private static List<string> CreateOptimizedStringPool(
     IEnumerable<DateTimeZone> zones,
     IEnumerable<TzdbZoneLocation> zoneLocations,
     IEnumerable<TzdbZone1970Location> zone1970Locations,
     WindowsZones cldrWindowsZones)
 {
     var optimizingWriter = new StringPoolOptimizingFakeWriter();
     foreach (var zone in zones)
     {
         optimizingWriter.WriteString(zone.Id);
         WriteZone(zone, optimizingWriter);
     }
     if (zoneLocations != null)
     {
         foreach (var location in zoneLocations)
         {
             location.Write(optimizingWriter);
         }
     }
     if (zone1970Locations != null)
     {
         foreach (var location in zone1970Locations)
         {
             location.Write(optimizingWriter);
         }
     }
     cldrWindowsZones.Write(optimizingWriter);
     return optimizingWriter.CreatePool();
 }
Beispiel #5
0
        /// <summary>
        /// Merge two WindowsZones objects together. The result has versions present in override,
        /// but falling back to the original for versions absent in the override. The set of MapZones
        /// in the result is the union of those in the original and override, but any ID/Territory
        /// pair present in both results in the override taking priority, unless the override has an
        /// empty "type" entry, in which case the entry is removed entirely.
        /// 
        /// While this method could reasonably be in WindowsZones class, it's only needed in
        /// TzdbCompiler - and here is as good a place as any.
        /// 
        /// The resulting MapZones will be ordered by Windows ID followed by territory.
        /// </summary>
        /// <param name="windowsZones">The original WindowsZones</param>
        /// <param name="overrideFile">The WindowsZones to override entries in the original</param>
        /// <returns>A merged zones object.</returns>
        internal static WindowsZones MergeWindowsZones(WindowsZones originalZones, WindowsZones overrideZones)
        {
            var version = overrideZones.Version == "" ? originalZones.Version : overrideZones.Version;
            var tzdbVersion = overrideZones.TzdbVersion == "" ? originalZones.TzdbVersion : overrideZones.TzdbVersion;
            var windowsVersion = overrideZones.WindowsVersion == "" ? originalZones.WindowsVersion : overrideZones.WindowsVersion;

            // Work everything out using dictionaries, and then sort.
            var mapZones = originalZones.MapZones.ToDictionary(mz => new { mz.WindowsId, mz.Territory });
            foreach (var overrideMapZone in overrideZones.MapZones)
            {
                var key = new { overrideMapZone.WindowsId, overrideMapZone.Territory };
                if (overrideMapZone.TzdbIds.Count == 0)
                {
                    mapZones.Remove(key);
                }
                else
                {
                    mapZones[key] = overrideMapZone;
                }
            }
            var mapZoneList = mapZones
                .OrderBy(pair => pair.Key.WindowsId)
                .ThenBy(pair => pair.Key.Territory)
                .Select(pair => pair.Value)
                .ToList();
            return new WindowsZones(version, tzdbVersion, windowsVersion, mapZoneList);
        }