github.com/gidoBOSSftw5731/go/src@v0.0.0-20210226122457-d24b0edbf019/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 "syscall" 15 ) 16 17 var zoneSources = []string{ 18 "/system/usr/share/zoneinfo/tzdata", 19 "/data/misc/zoneinfo/current/tzdata", 20 runtime.GOROOT() + "/lib/time/zoneinfo.zip", 21 } 22 23 func initLocal() { 24 // TODO(elias.naur): getprop persist.sys.timezone 25 localLoc = *UTC 26 } 27 28 func init() { 29 loadTzinfoFromTzdata = androidLoadTzinfoFromTzdata 30 } 31 32 func androidLoadTzinfoFromTzdata(file, name string) ([]byte, error) { 33 const ( 34 headersize = 12 + 3*4 35 namesize = 40 36 entrysize = namesize + 3*4 37 ) 38 if len(name) > namesize { 39 return nil, errors.New(name + " is longer than the maximum zone name length (40 bytes)") 40 } 41 fd, err := open(file) 42 if err != nil { 43 return nil, err 44 } 45 defer closefd(fd) 46 47 buf := make([]byte, headersize) 48 if err := preadn(fd, buf, 0); err != nil { 49 return nil, errors.New("corrupt tzdata file " + file) 50 } 51 d := dataIO{buf, false} 52 if magic := d.read(6); string(magic) != "tzdata" { 53 return nil, errors.New("corrupt tzdata file " + file) 54 } 55 d = dataIO{buf[12:], false} 56 indexOff, _ := d.big4() 57 dataOff, _ := d.big4() 58 indexSize := dataOff - indexOff 59 entrycount := indexSize / entrysize 60 buf = make([]byte, indexSize) 61 if err := preadn(fd, buf, int(indexOff)); err != nil { 62 return nil, errors.New("corrupt tzdata file " + file) 63 } 64 for i := 0; i < int(entrycount); i++ { 65 entry := buf[i*entrysize : (i+1)*entrysize] 66 // len(name) <= namesize is checked at function entry 67 if string(entry[:len(name)]) != name { 68 continue 69 } 70 d := dataIO{entry[namesize:], false} 71 off, _ := d.big4() 72 size, _ := d.big4() 73 buf := make([]byte, size) 74 if err := preadn(fd, buf, int(off+dataOff)); err != nil { 75 return nil, errors.New("corrupt tzdata file " + file) 76 } 77 return buf, nil 78 } 79 return nil, syscall.ENOENT 80 }