FreeRDP
Loading...
Searching...
No Matches
tzextract.cs
1using System;
2using System.IO;
3using System.Net;
4using System.Text;
5using System.Xml;
6using System.Xml.Linq;
7using System.Xml.Schema;
8
9internal class Program
10{
11 private static string app = AppDomain.CurrentDomain.FriendlyName;
12 private static TextWriter stderr = Console.Error;
13 private static TextWriter stdout = Console.Out;
14
15 private static void usage()
16 {
17 stderr.WriteLine("Usage:");
18 stderr.WriteLine(app + " <path to output files>");
19 Environment.Exit(1);
20 }
21
22 private static bool writeZoneMapC(string path)
23 {
24 string fname = "TimeZoneNameMap";
25 string fpath = Path.Combine(path, fname + "_static.h");
26
27 using (StreamWriter fs = new StreamWriter(fpath))
28 {
29 fs.WriteLine("/* Automatically generated by " + app + " */");
30 fs.WriteLine("");
31 fs.WriteLine("#include \"" + fname + ".h\"");
32 fs.WriteLine("");
33 fs.WriteLine("static const " + fname + "Entry " + fname + "[] ={");
34
35 bool first = true;
36 foreach (System.TimeZoneInfo tz in System.TimeZoneInfo.GetSystemTimeZones())
37 {
38 string iana;
39 System.TimeZoneInfo.TryConvertWindowsIdToIanaId(tz.Id, out iana);
40
41 StringBuilder sb = new StringBuilder();
42 if (!first)
43 sb.Append(",");
44 first = false;
45 sb.Append("{ \"");
46 sb.Append(tz.Id);
47 sb.Append("\", \"");
48 sb.Append(tz.StandardName);
49 sb.Append("\", \"");
50 sb.Append(tz.DisplayName);
51 sb.Append("\", \"");
52 sb.Append(tz.DaylightName);
53 sb.Append("\", \"");
54 sb.Append(iana);
55 sb.Append("\" }");
56 fs.WriteLine(sb.ToString());
57 }
58
59 fs.WriteLine("};");
60 fs.WriteLine("");
61 fs.WriteLine("static const size_t " + fname + "Size = ARRAYSIZE(" + fname + ");");
62 }
63 return true;
64 }
65
66 private static bool writeZoneMapJSON(string path)
67 {
68 string fname = "TimeZoneNameMap";
69 string fpath = Path.Combine(path, fname + ".json");
70
71 using (StreamWriter fs = new StreamWriter(fpath))
72 {
73 fs.WriteLine("{");
74 fs.WriteLine("\"TimeZoneNameMap\": [");
75
76 bool first = true;
77 foreach (System.TimeZoneInfo tz in System.TimeZoneInfo.GetSystemTimeZones())
78 {
79 string iana;
80 System.TimeZoneInfo.TryConvertWindowsIdToIanaId(tz.Id, out iana);
81
82 StringBuilder sb = new StringBuilder();
83 if (!first)
84 sb.Append(",");
85 first = false;
86 sb.Append("{ ");
87 sb.Append("\"Id\": \"");
88 sb.Append(tz.Id);
89 sb.Append("\", \"StandardName\": \"");
90 sb.Append(tz.StandardName);
91 sb.Append("\", \"DisplayName\": \"");
92 sb.Append(tz.DisplayName);
93 sb.Append("\", \"DaylightName\": \"");
94 sb.Append(tz.DaylightName);
95 sb.Append("\", \"Iana\": \"");
96 sb.Append(iana);
97 sb.Append("\" }");
98 fs.WriteLine(sb.ToString());
99 }
100
101 fs.WriteLine("]");
102 fs.WriteLine("}");
103 }
104 return true;
105 }
106
107 private static bool writeZoneMap(string path)
108 {
109 if (!writeZoneMapC(path))
110 return false;
111 if (!writeZoneMapJSON(path))
112 return false;
113 return true;
114 }
115
116 private static void onValidation(object sender, ValidationEventArgs e)
117 {
118 switch (e.Severity)
119 {
120 case XmlSeverityType.Warning:
121 case XmlSeverityType.Error:
122 stderr.WriteLine(e.ToString());
123 break;
124 default:
125 break;
126 }
127 }
128 private static bool updateWindowsIanaMap(string path)
129 {
130 string url =
131 "https://raw.githubusercontent.com/unicode-org/cldr/main/common/supplemental/windowsZones.xml";
132 string fname = "WindowsZones";
133 string fpath = Path.Combine(path, fname + ".c");
134
135 XmlDocument doc = new XmlDocument();
136 doc.Load(url);
137
138 stdout.WriteLine("Downloaded and parsed XML from '" + url + "'");
139
140 ValidationEventHandler handler = new ValidationEventHandler(onValidation);
141 // doc.Validate(handler);
142
143 XmlNodeList versions = doc.SelectNodes("//supplementalData/version");
144 XmlNodeList zones = doc.SelectNodes("//supplementalData/windowsZones/mapTimezones");
145 XmlNodeList mzones =
146 doc.SelectNodes("//supplementalData/windowsZones/mapTimezones/mapZone");
147
148 using (StreamWriter fs = new StreamWriter(fpath))
149 {
150 fs.WriteLine("/* Automatically generated by " + app);
151 fs.WriteLine(" *");
152 fs.WriteLine(" * url " + url);
153
154 foreach (XmlNode version in versions)
155 {
156 XmlNode nr = version.Attributes.GetNamedItem("number");
157 fs.WriteLine(" * version: " + nr.InnerText);
158 }
159
160 foreach (XmlNode node in zones)
161 {
162 XmlNode over = node.Attributes.GetNamedItem("otherVersion");
163 XmlNode tver = node.Attributes.GetNamedItem("typeVersion");
164 fs.WriteLine(" * mapTimezones: otherVersion: " + over.InnerText +
165 ", typeVersion: " + tver.InnerText);
166 }
167
168 fs.WriteLine(" */");
169 fs.WriteLine("");
170 fs.WriteLine("#include \"" + fname + ".h\"");
171 fs.WriteLine("");
172 fs.WriteLine("const WINDOWS_TZID_ENTRY " + fname + "[] = {");
173
174 foreach (XmlNode mzone in mzones)
175 {
176 XmlAttributeCollection attrs = mzone.Attributes;
177 XmlNode wzid = attrs.GetNamedItem("other");
178 XmlNode territory = attrs.GetNamedItem("territory");
179 XmlNode iana = attrs.GetNamedItem("type");
180 fs.WriteLine("\t{ \"" + iana.InnerText + "\", \"" + wzid.InnerText + "\" }, // " +
181 territory.InnerText);
182 }
183
184 fs.WriteLine("};");
185 fs.WriteLine("");
186 fs.WriteLine("const size_t " + fname + "NrElements = ARRAYSIZE(" + fname + ");");
187 }
188 stdout.WriteLine("Finished update");
189 return true;
190 }
191
192 private static void Main(string[] args)
193 {
194 try
195 {
196 if (args.Length == 0)
197 {
198 stderr.WriteLine("Missing arguments!");
199 usage();
200 }
201
202 DirectoryInfo info = new DirectoryInfo(args[0]);
203 if (!info.Exists)
204 {
205 stderr.WriteLine("Path '" + info.FullName + "' does not exist");
206 usage();
207 }
208
209 if (!writeZoneMap(info.FullName))
210 return;
211
212 updateWindowsIanaMap(info.FullName);
213 }
214 catch (Exception e)
215 {
216 stderr.WriteLine(e.ToString());
217 Environment.Exit(-23);
218 }
219 }
220}