1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- // Copyright 2016 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- // Parse the "tzdata" packed timezone file used on Android.
- // The format is lifted from ZoneInfoDB.java and ZoneInfo.java in
- // java/libcore/util in the AOSP.
- package time
- import (
- "errors"
- "runtime"
- "syscall"
- )
- var zoneSources = []string{
- "/system/usr/share/zoneinfo/tzdata",
- "/data/misc/zoneinfo/current/tzdata",
- runtime.GOROOT() + "/lib/time/zoneinfo.zip",
- }
- func initLocal() {
- // TODO(elias.naur): getprop persist.sys.timezone
- 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 := dataIO{buf, false}
- if magic := d.read(6); string(magic) != "tzdata" {
- return nil, errors.New("corrupt tzdata file " + file)
- }
- d = dataIO{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 := dataIO{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
- }
|