mirror of
https://github.com/golang/go
synced 2024-11-20 00:24:43 -07:00
Revert "time: enable ZONEINFO tzdata file support and error reporting"
This reverts commit 630d176e7d
.
Reason for revert: the CL moves a parser for what appears to be an
Android-specific file format into the main code and makes it available
on all platforms. Android-specific file formats should be limited to
Android.
Change-Id: I3f19fe03673d65ed1446a0dcf95e5986053e10c0
Reviewed-on: https://go-review.googlesource.com/77950
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
c09ee9d1ce
commit
02298ae11a
@ -272,7 +272,7 @@ var zoneinfoOnce sync.Once
|
|||||||
//
|
//
|
||||||
// The time zone database needed by LoadLocation may not be
|
// The time zone database needed by LoadLocation may not be
|
||||||
// present on all systems, especially non-Unix systems.
|
// present on all systems, especially non-Unix systems.
|
||||||
// LoadLocation looks in the directory, uncompressed zip file, or tzdata file
|
// LoadLocation looks in the directory or uncompressed zip file
|
||||||
// named by the ZONEINFO environment variable, if any, then looks in
|
// named by the ZONEINFO environment variable, if any, then looks in
|
||||||
// known installation locations on Unix systems,
|
// known installation locations on Unix systems,
|
||||||
// and finally looks in $GOROOT/lib/time/zoneinfo.zip.
|
// and finally looks in $GOROOT/lib/time/zoneinfo.zip.
|
||||||
@ -292,13 +292,14 @@ func LoadLocation(name string) (*Location, error) {
|
|||||||
env, _ := syscall.Getenv("ZONEINFO")
|
env, _ := syscall.Getenv("ZONEINFO")
|
||||||
zoneinfo = &env
|
zoneinfo = &env
|
||||||
})
|
})
|
||||||
sources := zoneSources
|
|
||||||
if *zoneinfo != "" {
|
if *zoneinfo != "" {
|
||||||
sources = make([]string, len(zoneSources)+1)
|
if zoneData, err := loadTzinfoFromDirOrZip(*zoneinfo, name); err == nil {
|
||||||
sources[0] = *zoneinfo
|
if z, err := newLocationFromTzinfo(name, zoneData); err == nil {
|
||||||
copy(sources[1:], zoneSources)
|
return z, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return loadLocation(name, sources)
|
return loadLocation(name, zoneSources)
|
||||||
}
|
}
|
||||||
|
|
||||||
// containsDotDot reports whether s contains "..".
|
// containsDotDot reports whether s contains "..".
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
package time
|
package time
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,3 +23,57 @@ func initLocal() {
|
|||||||
// TODO(elias.naur): getprop persist.sys.timezone
|
// TODO(elias.naur): getprop persist.sys.timezone
|
||||||
localLoc = *UTC
|
localLoc = *UTC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
loadTzinfoFromTzdata = androidLoadTzinfoFromTzdata
|
||||||
|
}
|
||||||
|
|
||||||
|
func androidLoadTzinfoFromTzdata(file, name string) ([]byte, error) {
|
||||||
|
const (
|
||||||
|
headersize = 12 + 3*4
|
||||||
|
namesize = 40
|
||||||
|
entrysize = namesize + 3*4
|
||||||
|
)
|
||||||
|
if len(name) > namesize {
|
||||||
|
return nil, errors.New(name + " is longer than the maximum zone name length (40 bytes)")
|
||||||
|
}
|
||||||
|
fd, err := open(file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer closefd(fd)
|
||||||
|
|
||||||
|
buf := make([]byte, headersize)
|
||||||
|
if err := preadn(fd, buf, 0); err != nil {
|
||||||
|
return nil, errors.New("corrupt tzdata file " + file)
|
||||||
|
}
|
||||||
|
d := data{buf, false}
|
||||||
|
if magic := d.read(6); string(magic) != "tzdata" {
|
||||||
|
return nil, errors.New("corrupt tzdata file " + file)
|
||||||
|
}
|
||||||
|
d = data{buf[12:], false}
|
||||||
|
indexOff, _ := d.big4()
|
||||||
|
dataOff, _ := d.big4()
|
||||||
|
indexSize := dataOff - indexOff
|
||||||
|
entrycount := indexSize / entrysize
|
||||||
|
buf = make([]byte, indexSize)
|
||||||
|
if err := preadn(fd, buf, int(indexOff)); err != nil {
|
||||||
|
return nil, errors.New("corrupt tzdata file " + file)
|
||||||
|
}
|
||||||
|
for i := 0; i < int(entrycount); i++ {
|
||||||
|
entry := buf[i*entrysize : (i+1)*entrysize]
|
||||||
|
// len(name) <= namesize is checked at function entry
|
||||||
|
if string(entry[:len(name)]) != name {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
d := data{entry[namesize:], false}
|
||||||
|
off, _ := d.big4()
|
||||||
|
size, _ := d.big4()
|
||||||
|
buf := make([]byte, size)
|
||||||
|
if err := preadn(fd, buf, int(off+dataOff)); err != nil {
|
||||||
|
return nil, errors.New("corrupt tzdata file " + file)
|
||||||
|
}
|
||||||
|
return buf, nil
|
||||||
|
}
|
||||||
|
return nil, errors.New("cannot find " + name + " in tzdata file " + file)
|
||||||
|
}
|
||||||
|
@ -220,6 +220,18 @@ func newLocationFromTzinfo(name string, Tzinfo []byte) (*Location, error) {
|
|||||||
return l, nil
|
return l, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// loadTzinfoFromDirOrZip returns the contents of the file with the given name
|
||||||
|
// in dir. dir can either be an uncompressed zip file, or a directory.
|
||||||
|
func loadTzinfoFromDirOrZip(dir, name string) ([]byte, error) {
|
||||||
|
if len(dir) > 4 && dir[len(dir)-4:] == ".zip" {
|
||||||
|
return loadTzinfoFromZip(dir, name)
|
||||||
|
}
|
||||||
|
if dir != "" {
|
||||||
|
name = dir + "/" + name
|
||||||
|
}
|
||||||
|
return readFile(name)
|
||||||
|
}
|
||||||
|
|
||||||
// There are 500+ zoneinfo files. Rather than distribute them all
|
// There are 500+ zoneinfo files. Rather than distribute them all
|
||||||
// individually, we ship them in an uncompressed zip file.
|
// individually, we ship them in an uncompressed zip file.
|
||||||
// Used this way, the zip file format serves as a commonly readable
|
// Used this way, the zip file format serves as a commonly readable
|
||||||
@ -351,61 +363,13 @@ func loadTzinfoFromZip(zipfile, name string) ([]byte, error) {
|
|||||||
return buf, nil
|
return buf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, syscall.ENOENT
|
return nil, errors.New("cannot find " + name + " in zip file " + zipfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadTzinfoFromTzdata returns the time zone information of the time zone
|
// loadTzinfoFromTzdata returns the time zone information of the time zone
|
||||||
// with the given name, from a tzdata database file as they are typically
|
// with the given name, from a tzdata database file as they are typically
|
||||||
// found on android.
|
// found on android.
|
||||||
func loadTzinfoFromTzdata(file, name string) ([]byte, error) {
|
var loadTzinfoFromTzdata func(file, name string) ([]byte, error)
|
||||||
const (
|
|
||||||
headersize = 12 + 3*4
|
|
||||||
namesize = 40
|
|
||||||
entrysize = namesize + 3*4
|
|
||||||
)
|
|
||||||
if len(name) > namesize {
|
|
||||||
return nil, errors.New(name + " is longer than the maximum zone name length (40 bytes)")
|
|
||||||
}
|
|
||||||
fd, err := open(file)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer closefd(fd)
|
|
||||||
|
|
||||||
buf := make([]byte, headersize)
|
|
||||||
if err := preadn(fd, buf, 0); err != nil {
|
|
||||||
return nil, errors.New("corrupt tzdata file " + file)
|
|
||||||
}
|
|
||||||
d := data{buf, false}
|
|
||||||
if magic := d.read(6); string(magic) != "tzdata" {
|
|
||||||
return nil, errors.New("corrupt tzdata file " + file)
|
|
||||||
}
|
|
||||||
d = data{buf[12:], false}
|
|
||||||
indexOff, _ := d.big4()
|
|
||||||
dataOff, _ := d.big4()
|
|
||||||
indexSize := dataOff - indexOff
|
|
||||||
entrycount := indexSize / entrysize
|
|
||||||
buf = make([]byte, indexSize)
|
|
||||||
if err := preadn(fd, buf, int(indexOff)); err != nil {
|
|
||||||
return nil, errors.New("corrupt tzdata file " + file)
|
|
||||||
}
|
|
||||||
for i := 0; i < int(entrycount); i++ {
|
|
||||||
entry := buf[i*entrysize : (i+1)*entrysize]
|
|
||||||
// len(name) <= namesize is checked at function entry
|
|
||||||
if string(entry[:len(name)]) != name {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
d := data{entry[namesize:], false}
|
|
||||||
off, _ := d.big4()
|
|
||||||
size, _ := d.big4()
|
|
||||||
buf := make([]byte, size)
|
|
||||||
if err := preadn(fd, buf, int(off+dataOff)); err != nil {
|
|
||||||
return nil, errors.New("corrupt tzdata file " + file)
|
|
||||||
}
|
|
||||||
return buf, nil
|
|
||||||
}
|
|
||||||
return nil, syscall.ENOENT
|
|
||||||
}
|
|
||||||
|
|
||||||
// loadTzinfo returns the time zone information of the time zone
|
// loadTzinfo returns the time zone information of the time zone
|
||||||
// with the given name, from a given source. A source may be a
|
// with the given name, from a given source. A source may be a
|
||||||
@ -414,13 +378,8 @@ func loadTzinfoFromTzdata(file, name string) ([]byte, error) {
|
|||||||
func loadTzinfo(name string, source string) ([]byte, error) {
|
func loadTzinfo(name string, source string) ([]byte, error) {
|
||||||
if len(source) >= 6 && source[len(source)-6:] == "tzdata" {
|
if len(source) >= 6 && source[len(source)-6:] == "tzdata" {
|
||||||
return loadTzinfoFromTzdata(source, name)
|
return loadTzinfoFromTzdata(source, name)
|
||||||
} else if len(source) > 4 && source[len(source)-4:] == ".zip" {
|
|
||||||
return loadTzinfoFromZip(source, name)
|
|
||||||
}
|
}
|
||||||
if source != "" {
|
return loadTzinfoFromDirOrZip(source, name)
|
||||||
name = source + "/" + name
|
|
||||||
}
|
|
||||||
return readFile(name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadLocation returns the Location with the given name from one of
|
// loadLocation returns the Location with the given name from one of
|
||||||
|
Loading…
Reference in New Issue
Block a user