| ... | ... | @@ -1,3 +1,6 @@ |
| 1 | //! The Time Zone Information Format (TZif) |
| 2 | //! https://datatracker.ietf.org/doc/html/rfc8536 |
| 3 | |
| 1 | 4 | const builtin = @import("builtin"); |
| 2 | 5 | |
| 3 | 6 | const std = @import("std.zig"); |
| ... | ... | @@ -58,30 +61,26 @@ pub const Tz = struct { |
| 58 | 61 | }; |
| 59 | 62 | |
| 60 | 63 | pub fn parse(allocator: Allocator, reader: *Reader) !Tz { |
| 61 | | var legacy_header = try reader.takeStruct(Header, .little); |
| 64 | const legacy_header = try reader.takeStruct(Header, .big); |
| 62 | 65 | if (!std.mem.eql(u8, &legacy_header.magic, "TZif")) return error.BadHeader; |
| 63 | | if (legacy_header.version != 0 and legacy_header.version != '2' and legacy_header.version != '3') return error.BadVersion; |
| 64 | | |
| 65 | | if (builtin.target.cpu.arch.endian() != std.builtin.Endian.big) { |
| 66 | | std.mem.byteSwapAllFields(@TypeOf(legacy_header.counts), &legacy_header.counts); |
| 67 | | } |
| 66 | if (legacy_header.version != 0 and legacy_header.version != '2' and legacy_header.version != '3') |
| 67 | return error.BadVersion; |
| 68 | 68 | |
| 69 | | if (legacy_header.version == 0) { |
| 69 | if (legacy_header.version == 0) |
| 70 | 70 | return parseBlock(allocator, reader, legacy_header, true); |
| 71 | | } else { |
| 72 | | // If the format is modern, just skip over the legacy data |
| 73 | | const skipv = legacy_header.counts.timecnt * 5 + legacy_header.counts.typecnt * 6 + legacy_header.counts.charcnt + legacy_header.counts.leapcnt * 8 + legacy_header.counts.isstdcnt + legacy_header.counts.isutcnt; |
| 74 | | try reader.discardAll(skipv); |
| 75 | | |
| 76 | | var header = try reader.takeStruct(Header, .little); |
| 77 | | if (!std.mem.eql(u8, &header.magic, "TZif")) return error.BadHeader; |
| 78 | | if (header.version != '2' and header.version != '3') return error.BadVersion; |
| 79 | | if (builtin.target.cpu.arch.endian() != std.builtin.Endian.big) { |
| 80 | | std.mem.byteSwapAllFields(@TypeOf(header.counts), &header.counts); |
| 81 | | } |
| 82 | 71 | |
| 83 | | return parseBlock(allocator, reader, header, false); |
| 84 | | } |
| 72 | // If the format is modern, just skip over the legacy data |
| 73 | const skip_n = legacy_header.counts.timecnt * 5 + |
| 74 | legacy_header.counts.typecnt * 6 + |
| 75 | legacy_header.counts.charcnt + legacy_header.counts.leapcnt * 8 + |
| 76 | legacy_header.counts.isstdcnt + legacy_header.counts.isutcnt; |
| 77 | try reader.discardAll(skip_n); |
| 78 | |
| 79 | var header = try reader.takeStruct(Header, .big); |
| 80 | if (!std.mem.eql(u8, &header.magic, "TZif")) return error.BadHeader; |
| 81 | if (header.version != '2' and header.version != '3') return error.BadVersion; |
| 82 | |
| 83 | return parseBlock(allocator, reader, header, false); |
| 85 | 84 | } |
| 86 | 85 | |
| 87 | 86 | fn parseBlock(allocator: Allocator, reader: *Reader, header: Header, legacy: bool) !Tz { |