diff options
Diffstat (limited to 'libgo/go/time/zoneinfo_read.go')
-rw-r--r-- | libgo/go/time/zoneinfo_read.go | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/libgo/go/time/zoneinfo_read.go b/libgo/go/time/zoneinfo_read.go index 1e559a6..c242972 100644 --- a/libgo/go/time/zoneinfo_read.go +++ b/libgo/go/time/zoneinfo_read.go @@ -13,8 +13,22 @@ import ( "errors" "runtime" "syscall" + _ "unsafe" // for go:linkname ) +// registerLoadFromEmbeddedTZData is called by the time/tzdata package, +// if it is imported. +//go:linkname registerLoadFromEmbeddedTZData +func registerLoadFromEmbeddedTZData(f func(string) (string, error)) { + loadFromEmbeddedTZData = f +} + +// loadFromEmbeddedTZData is used to load a specific tzdata file +// from tzdata information embedded in the binary itself. +// This is set when the time/tzdata package is imported, +// via registerLoadFromEmbeddedTzdata. +var loadFromEmbeddedTZData func(zipname string) (string, error) + // maxFileSize is the max permitted size of files read by readFile. // As reference, the zoneinfo.zip distributed by Go is ~350 KB, // so 10MB is overkill. @@ -78,6 +92,13 @@ func (d *dataIO) byte() (n byte, ok bool) { return p[0], true } +// read returns the read of the data in the buffer. +func (d *dataIO) rest() []byte { + r := d.p + d.p = nil + return r +} + // Make a string by stopping at the first NUL func byteString(p []byte) string { for i := 0; i < len(p); i++ { @@ -213,6 +234,12 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) { return nil, badData } + var extend string + rest := d.rest() + if len(rest) > 2 && rest[0] == '\n' && rest[len(rest)-1] == '\n' { + extend = string(rest[1 : len(rest)-1]) + } + // Now we can build up a useful data structure. // First the zone information. // utcoff[4] isdst[1] nameindex[1] @@ -289,7 +316,7 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) { } // Committed to succeed. - l := &Location{zone: zone, tx: tx, name: name} + l := &Location{zone: zone, tx: tx, name: name, extend: extend} // Fill in the cache with information about right now, // since that will be the most common lookup. @@ -486,6 +513,17 @@ func loadLocation(name string, sources []string) (z *Location, firstErr error) { firstErr = err } } + if loadFromEmbeddedTZData != nil { + zonedata, err := loadFromEmbeddedTZData(name) + if err == nil { + if z, err = LoadLocationFromTZData(name, []byte(zonedata)); err == nil { + return z, nil + } + } + if firstErr == nil && err != syscall.ENOENT { + firstErr = err + } + } if firstErr != nil { return nil, firstErr } |