OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 ********************************************************************** | 3 ********************************************************************** |
4 * Copyright (c) 2003-2010, International Business Machines | 4 * Copyright (c) 2003-2014, International Business Machines |
5 * Corporation and others. All Rights Reserved. | 5 * Corporation and others. All Rights Reserved. |
6 ********************************************************************** | 6 ********************************************************************** |
7 * Author: Alan Liu | 7 * Author: Alan Liu |
8 * Created: July 10 2003 | 8 * Created: July 10 2003 |
9 * Since: ICU 2.8 | 9 * Since: ICU 2.8 |
10 ********************************************************************** | 10 ********************************************************************** |
11 */ | 11 */ |
12 #include "tzfile.h" // from Olson tzcode archive, copied to this dir | 12 #include "tzfile.h" // from Olson tzcode archive, copied to this dir |
13 | 13 |
14 #ifdef WIN32 | 14 #ifdef WIN32 |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 // means the user is passing in a "normal" zoneinfo directory, or | 297 // means the user is passing in a "normal" zoneinfo directory, or |
298 // a zoneinfo directory that is polluted with other files, or that | 298 // a zoneinfo directory that is polluted with other files, or that |
299 // the user passed in the wrong directory. | 299 // the user passed in the wrong directory. |
300 char buf[32]; | 300 char buf[32]; |
301 file.read(buf, 4); | 301 file.read(buf, 4); |
302 if (strncmp(buf, TZ_ICU_MAGIC, 4) != 0) { | 302 if (strncmp(buf, TZ_ICU_MAGIC, 4) != 0) { |
303 throw invalid_argument("TZ_ICU_MAGIC signature missing"); | 303 throw invalid_argument("TZ_ICU_MAGIC signature missing"); |
304 } | 304 } |
305 // skip additional Olson byte version | 305 // skip additional Olson byte version |
306 file.read(buf, 1); | 306 file.read(buf, 1); |
307 // if '\0', we have just one copy of data, if '2', there is additional | 307 // if '\0', we have just one copy of data, if '2' or '3', there is additiona
l |
308 // 64 bit version at the end. | 308 // 64 bit version at the end. |
309 if(buf[0]!=0 && buf[0]!='2') { | 309 if(buf[0]!=0 && buf[0]!='2' && buf[0]!='3') { |
310 throw invalid_argument("Bad Olson version info"); | 310 throw invalid_argument("Bad Olson version info"); |
311 } | 311 } |
312 | 312 |
313 // Read reserved bytes. The first of these will be a version byte. | 313 // Read reserved bytes. The first of these will be a version byte. |
314 file.read(buf, 15); | 314 file.read(buf, 15); |
315 if (*(ICUZoneinfoVersion*)&buf != TZ_ICU_VERSION) { | 315 if (*(ICUZoneinfoVersion*)&buf != TZ_ICU_VERSION) { |
316 throw invalid_argument("File version mismatch"); | 316 throw invalid_argument("File version mismatch"); |
317 } | 317 } |
318 | 318 |
319 // Read array sizes | 319 // Read array sizes |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 ostringstream os; | 822 ostringstream os; |
823 if (month < 0 || month >= 12) { | 823 if (month < 0 || month >= 12) { |
824 os << "Invalid input month " << month; | 824 os << "Invalid input month " << month; |
825 } | 825 } |
826 if (dom < 1 || dom > MONTH_LEN[month]) { | 826 if (dom < 1 || dom > MONTH_LEN[month]) { |
827 os << "Invalid input day of month " << dom; | 827 os << "Invalid input day of month " << dom; |
828 } | 828 } |
829 if (mode != DOM && (dow < 0 || dow >= 7)) { | 829 if (mode != DOM && (dow < 0 || dow >= 7)) { |
830 os << "Invalid input day of week " << dow; | 830 os << "Invalid input day of week " << dow; |
831 } | 831 } |
832 if (offset < 0 || offset > HOUR) { | 832 if (offset < 0 || offset > (2 * HOUR)) { |
833 os << "Invalid input offset " << offset; | 833 os << "Invalid input offset " << offset; |
834 } | 834 } |
835 if (isgmt && !isstd) { | 835 if (isgmt && !isstd) { |
836 os << "Invalid input isgmt && !isstd"; | 836 os << "Invalid input isgmt && !isstd"; |
837 } | 837 } |
838 if (!os.str().empty()) { | 838 if (!os.str().empty()) { |
839 os << " for rule " | 839 os << " for rule " |
840 << id | 840 << id |
841 << _mode | 841 << _mode |
842 << month << dom << dow << time | 842 << month << dom << dow << time |
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1574 ZONEINFO[olson].addAlias(zoneIDs[*j]); | 1574 ZONEINFO[olson].addAlias(zoneIDs[*j]); |
1575 } | 1575 } |
1576 } | 1576 } |
1577 | 1577 |
1578 // Once merging of final data is complete, we can optimize the type list | 1578 // Once merging of final data is complete, we can optimize the type list |
1579 for (ZoneMap::iterator i=ZONEINFO.begin(); i!=ZONEINFO.end(); ++i) { | 1579 for (ZoneMap::iterator i=ZONEINFO.begin(); i!=ZONEINFO.end(); ++i) { |
1580 i->second.optimizeTypeList(); | 1580 i->second.optimizeTypeList(); |
1581 } | 1581 } |
1582 | 1582 |
1583 // Create the country map | 1583 // Create the country map |
| 1584 map<string, string> icuRegions; // ICU's custom zone -> country overr
ide |
1584 map<string, set<string> > countryMap; // country -> set of zones | 1585 map<string, set<string> > countryMap; // country -> set of zones |
1585 map<string, string> reverseCountryMap; // zone -> country | 1586 map<string, string> reverseCountryMap; // zone -> country |
| 1587 |
| 1588 try { |
| 1589 // Read icuregions file to collect ICU's own zone-region mapping data. |
| 1590 ifstream frg(ICU_REGIONS); |
| 1591 if (frg) { |
| 1592 string line; |
| 1593 while (getline(frg, line)) { |
| 1594 if (line[0] == '#') continue; |
| 1595 |
| 1596 string zone, country; |
| 1597 istringstream is(line); |
| 1598 is >> zone >> country; |
| 1599 if (zone.size() == 0) continue; |
| 1600 if (country.size() < 2) { |
| 1601 cerr << "Error: Can't parse " << line << " in " << ICU_REGIO
NS << endl; |
| 1602 return 1; |
| 1603 } |
| 1604 icuRegions[zone] = country; |
| 1605 } |
| 1606 } else { |
| 1607 cout << "No custom region map [icuregions]" << endl; |
| 1608 } |
| 1609 } catch (const exception& error) { |
| 1610 cerr << "Error: While reading " << ICU_REGIONS << ": " << error.what() <
< endl; |
| 1611 return 1; |
| 1612 } |
| 1613 |
1586 try { | 1614 try { |
1587 ifstream f(zonetab.c_str()); | 1615 ifstream f(zonetab.c_str()); |
1588 if (!f) { | 1616 if (!f) { |
1589 cerr << "Error: Unable to open " << zonetab << endl; | 1617 cerr << "Error: Unable to open " << zonetab << endl; |
1590 return 1; | 1618 return 1; |
1591 } | 1619 } |
1592 int32_t n = 0; | 1620 int32_t n = 0; |
1593 string line; | 1621 string line; |
1594 while (getline(f, line)) { | 1622 while (getline(f, line)) { |
1595 string::size_type lb = line.find('#'); | 1623 string::size_type lb = line.find('#'); |
1596 if (lb != string::npos) { | 1624 if (lb != string::npos) { |
1597 line.resize(lb); // trim comments | 1625 line.resize(lb); // trim comments |
1598 } | 1626 } |
1599 string country, coord, zone; | 1627 string country, coord, zone; |
1600 istringstream is(line); | 1628 istringstream is(line); |
1601 is >> country >> coord >> zone; | 1629 is >> country >> coord >> zone; |
1602 if (country.size() == 0) continue; | 1630 if (country.size() == 0) continue; |
1603 if (country.size() != 2 || zone.size() < 1) { | 1631 if (country.size() != 2 || zone.size() < 1) { |
1604 cerr << "Error: Can't parse " << line << " in " << zonetab << en
dl; | 1632 cerr << "Error: Can't parse " << line << " in " << zonetab << en
dl; |
1605 return 1; | 1633 return 1; |
1606 } | 1634 } |
1607 if (ZONEINFO.find(zone) == ZONEINFO.end()) { | 1635 if (ZONEINFO.find(zone) == ZONEINFO.end()) { |
1608 cerr << "Error: Country maps to invalid zone " << zone | 1636 cerr << "Error: Country maps to invalid zone " << zone |
1609 << " in " << zonetab << endl; | 1637 << " in " << zonetab << endl; |
1610 return 1; | 1638 return 1; |
1611 } | 1639 } |
| 1640 if (icuRegions.find(zone) != icuRegions.end()) { |
| 1641 // Custom override |
| 1642 string customCountry = icuRegions[zone]; |
| 1643 cout << "Region Mapping: custom override for " << zone |
| 1644 << " " << country << " -> " << customCountry << endl; |
| 1645 country = customCountry; |
| 1646 } |
1612 countryMap[country].insert(zone); | 1647 countryMap[country].insert(zone); |
1613 reverseCountryMap[zone] = country; | 1648 reverseCountryMap[zone] = country; |
1614 //cerr << (n+1) << ": " << country << " <=> " << zone << endl; | 1649 //cerr << (n+1) << ": " << country << " <=> " << zone << endl; |
1615 ++n; | 1650 ++n; |
1616 } | 1651 } |
1617 cout << "Finished reading " << n | 1652 cout << "Finished reading " << n |
1618 << " country entries from " << zonetab << endl; | 1653 << " country entries from " << zonetab << endl; |
1619 } catch (const exception& error) { | 1654 } catch (const exception& error) { |
1620 cerr << "Error: While reading " << zonetab << ": " << error.what() << en
dl; | 1655 cerr << "Error: While reading " << zonetab << ": " << error.what() << en
dl; |
1621 return 1; | 1656 return 1; |
1622 } | 1657 } |
1623 | 1658 |
| 1659 // Merge ICU's own zone-region mapping data |
| 1660 for (map<string,string>::const_iterator i = icuRegions.begin(); |
| 1661 i != icuRegions.end(); ++i) { |
| 1662 const string& zid(i->first); |
| 1663 if (reverseCountryMap.find(zid) != reverseCountryMap.end()) { |
| 1664 continue; |
| 1665 } |
| 1666 cout << "Region Mapping: custom data zone=" << zid |
| 1667 << ", region=" << i->second << endl; |
| 1668 |
| 1669 reverseCountryMap[zid] = i->second; |
| 1670 countryMap[i->second].insert(zid); |
| 1671 } |
| 1672 |
1624 // Merge ICU aliases into country map. Don't merge any alias | 1673 // Merge ICU aliases into country map. Don't merge any alias |
1625 // that already has a country map, since that doesn't make sense. | 1674 // that already has a country map, since that doesn't make sense. |
1626 // E.g. "Link Europe/Oslo Arctic/Longyearbyen" doesn't mean we | 1675 // E.g. "Link Europe/Oslo Arctic/Longyearbyen" doesn't mean we |
1627 // should cross-map the countries between these two zones. | 1676 // should cross-map the countries between these two zones. |
1628 for (map<string,set<string> >::const_iterator i = links.begin(); | 1677 for (map<string,set<string> >::const_iterator i = links.begin(); |
1629 i!=links.end(); ++i) { | 1678 i!=links.end(); ++i) { |
1630 const string& olson(i->first); | 1679 const string& olson(i->first); |
1631 if (reverseCountryMap.find(olson) == reverseCountryMap.end()) { | 1680 if (reverseCountryMap.find(olson) == reverseCountryMap.end()) { |
1632 continue; | 1681 continue; |
1633 } | 1682 } |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1752 file.close(); | 1801 file.close(); |
1753 | 1802 |
1754 if (file) { // recheck error bit | 1803 if (file) { // recheck error bit |
1755 cout << "Finished writing " << TZ_RESOURCE_NAME << ".txt" << endl; | 1804 cout << "Finished writing " << TZ_RESOURCE_NAME << ".txt" << endl; |
1756 } else { | 1805 } else { |
1757 cerr << "Error: Unable to open/write to " << TZ_RESOURCE_NAME << ".txt"
<< endl; | 1806 cerr << "Error: Unable to open/write to " << TZ_RESOURCE_NAME << ".txt"
<< endl; |
1758 return 1; | 1807 return 1; |
1759 } | 1808 } |
1760 } | 1809 } |
1761 //eof | 1810 //eof |
OLD | NEW |