Esempio n. 1
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));
        }
Esempio n. 2
0
        /// <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());
        }
Esempio n. 3
0
        public void Write(TzdbDatabase database, WindowsZones cldrWindowsZones)
        {
            var timeZoneMap = new Dictionary <string, string>();

            foreach (var zone in database.GenerateDateTimeZones())
            {
                timeZoneMap.Add(zone.Id, zone.Id);
                WriteTimeZone(zone);
            }

            // Normalize the aliases
            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);
            }
            resourceWriter.AddResource(TzdbResourceData.VersionKey, database.Version);
            WriteDictionary(TzdbResourceData.IdMapKey, timeZoneMap);
            WriteDictionary(TzdbResourceData.WindowsToPosixMapKey, cldrWindowsZones.PrimaryMapping);
            resourceWriter.AddResource(TzdbResourceData.WindowsToPosixMapVersionKey, cldrWindowsZones.Version);
            resourceWriter.Close();
        }
Esempio n. 4
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);
 }
Esempio n. 5
0
        private TzdbResourceData(ResourceSet source)
        {
            this.source = source;
            tzdbIdMap   = CheckKey(LoadDictionary(source, IdMapKey), IdMapKey);
            tzdbVersion = CheckKey(source.GetString(VersionKey), VersionKey);
            var windowsMappingVersion = CheckKey(source.GetString(WindowsToPosixMapVersionKey), WindowsToPosixMapVersionKey);
            var windowsMapping        = CheckKey(LoadDictionary(source, WindowsToPosixMapKey), WindowsToPosixMapKey);

            this.windowsMapping = WindowsZones.FromPrimaryMapping(windowsMappingVersion, windowsMapping);
        }
Esempio n. 6
0
        public void Properties()
        {
            var zones = new WindowsZones("version", "tzdbVersion", "windowsVersion", new[] { MapZone1, MapZone2, MapZone3 });

            Assert.AreEqual("version", zones.Version);
            Assert.AreEqual("tzdbVersion", zones.TzdbVersion);
            Assert.AreEqual("windowsVersion", zones.WindowsVersion);
            Assert.AreEqual("primaryId2", zones.PrimaryMapping["windowsId2"]);
            Assert.AreEqual("primaryId3", zones.PrimaryMapping["windowsId3"]);
            Assert.AreEqual(new[] { MapZone1, MapZone2, MapZone3 }, zones.MapZones);
        }
Esempio n. 7
0
        private static void ReadWindowsZones(DateTimeZoneReader reader)
        {
            var zones = WindowsZones.Read(reader);

            Console.WriteLine($"  Version: {zones.Version}");
            Console.WriteLine($"  TZDB version: {zones.TzdbVersion}");
            Console.WriteLine($"  Windows version: {zones.WindowsVersion}");
            Console.WriteLine($"  Mappings: {zones.MapZones.Count}");
            foreach (var mapZone in zones.MapZones)
            {
                Console.WriteLine($"  {mapZone}");
            }
        }
Esempio n. 8
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);
        }
Esempio n. 9
0
        private TzdbStreamData(Builder builder)
        {
            stringPool     = CheckNotNull(builder.stringPool, "string pool");
            tzdbIdMap      = CheckNotNull(builder.tzdbIdMap, "TZDB alias map");
            tzdbVersion    = CheckNotNull(builder.tzdbVersion, "TZDB version");
            windowsMapping = CheckNotNull(builder.windowsMapping, "CLDR Supplemental Windows Zones");
            zoneFields     = builder.zoneFields;
            zoneLocations  = builder.zoneLocations;

            // Add in the canonical IDs as mappings to themselves.
            foreach (var id in zoneFields.Keys)
            {
                tzdbIdMap[id] = id;
            }

            windowsAdditionalStandardNameToIdMapping = CheckNotNull(builder.windowsAdditionalStandardNameToIdMapping,
                                                                    "Windows additional standard name to ID mapping");
        }
Esempio n. 10
0
        public void ReadWrite()
        {
            var zones = new WindowsZones("version", "tzdbVersion", "windowsVersion", new[] { MapZone1, MapZone2, MapZone3 });

            var stream = new MemoryStream();
            var writer = new DateTimeZoneWriter(stream, null);

            zones.Write(writer);
            stream.Position = 0;

            var reader = new DateTimeZoneReader(stream, null);
            var zones2 = WindowsZones.Read(reader);

            Assert.AreEqual("version", zones2.Version);
            Assert.AreEqual("tzdbVersion", zones2.TzdbVersion);
            Assert.AreEqual("windowsVersion", zones2.WindowsVersion);
            Assert.AreEqual("primaryId2", zones2.PrimaryMapping["windowsId2"]);
            Assert.AreEqual("primaryId3", zones2.PrimaryMapping["windowsId3"]);
            Assert.AreEqual(new[] { MapZone1, MapZone2, MapZone3 }, zones2.MapZones);
        }
Esempio n. 11
0
 internal void HandleSupplementalWindowsZonesField(TzdbStreamField field)
 {
     CheckSingleField(field, windowsMapping);
     windowsMapping = field.ExtractSingleValue(WindowsZones.Read, stringPool);
 }
Esempio n. 12
0
        public void Write(TzdbDatabase database, WindowsZones cldrWindowsZones)
        {
            FieldCollection fields = new FieldCollection();

            var zones      = database.GenerateDateTimeZones().ToList();
            var stringPool = CreateOptimizedStringPool(zones, database.ZoneLocations, 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
                (PclSupport.StandardNameToIdMap.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);
                }
            }

            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);

            stream.Close();
        }