github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/time/zoneinfo_android.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Parse the "tzdata" packed timezone file used on Android. 6 // The format is lifted from ZoneInfoDB.java and ZoneInfo.java in 7 // java/libcore/util in the AOSP. 8 9 package time 10 11 import ( 12 "errors" 13 "runtime" 14 ) 15 16 var zoneSources = []string{ 17 "/system/usr/share/zoneinfo/tzdata", 18 "/data/misc/zoneinfo/current/tzdata", 19 runtime.GOROOT() + "/lib/time/zoneinfo.zip", 20 } 21 22 func initLocal() { 23 // TODO(elias.naur): getprop persist.sys.timezone 24 localLoc = *UTC 25 } 26 27 func init() { 28 loadTzinfoFromTzdata = androidLoadTzinfoFromTzdata 29 } 30 31 func androidLoadTzinfoFromTzdata(file, name string) ([]byte, error) { 32 const ( 33 headersize = 12 + 3*4 34 namesize = 40 35 entrysize = namesize + 3*4 36 ) 37 if len(name) > namesize { 38 return nil, errors.New(name + " is longer than the maximum zone name length (40 bytes)") 39 } 40 fd, err := open(file) 41 if err != nil { 42 return nil, err 43 } 44 defer closefd(fd) 45 46 buf := make([]byte, headersize) 47 if err := preadn(fd, buf, 0); err != nil { 48 return nil, errors.New("corrupt tzdata file " + file) 49 } 50 d := dataIO{buf, false} 51 if magic := d.read(6); string(magic) != "tzdata" { 52 return nil, errors.New("corrupt tzdata file " + file) 53 } 54 d = dataIO{buf[12:], false} 55 indexOff, _ := d.big4() 56 dataOff, _ := d.big4() 57 indexSize := dataOff - indexOff 58 entrycount := indexSize / entrysize 59 buf = make([]byte, indexSize) 60 if err := preadn(fd, buf, int(indexOff)); err != nil { 61 return nil, errors.New("corrupt tzdata file " + file) 62 } 63 for i := 0; i < int(entrycount); i++ { 64 entry := buf[i*entrysize : (i+1)*entrysize] 65 // len(name) <= namesize is checked at function entry 66 if string(entry[:len(name)]) != name { 67 continue 68 } 69 d := dataIO{entry[namesize:], false} 70 off, _ := d.big4() 71 size, _ := d.big4() 72 buf := make([]byte, size) 73 if err := preadn(fd, buf, int(off+dataOff)); err != nil { 74 return nil, errors.New("corrupt tzdata file " + file) 75 } 76 return buf, nil 77 } 78 return nil, errors.New("cannot find " + name + " in tzdata file " + file) 79 }