ref: a74746cf0a22bd451ae9a57f350cbf1c0d7fd3f9
parent: 6f893e4ef65b27ec2241b8375a465bbf41e3622b
author: Ori Bernstein <[email protected]>
date: Mon Aug 26 22:57:14 EDT 2013
Add zoneinfo parser. Not part of build yet.
--- /dev/null
+++ b/libstd/zoneinfo.myr
@@ -1,0 +1,124 @@
+use "alloc.use"
+use "die.use"
+use "sleq.use"
+use "slurp.use"
+use "sys.use"
+use "types.use"
+use "fmt.use"
+
+pkg _timezone =
+ type zifile
+ const load : (file : byte[:] -> zifile#)
+;;
+
+type zifile = struct
+ time : int32[:]
+ timetype: byte[:]
+ ttinfo : ttinfo[:]
+ abbrev : byte[:]
+ leap : int32[2][:]
+ isstd : byte[:]
+ isgmt : byte[:]
+;;
+
+type ttinfo = struct
+ gmtoff : int32
+ isdst : byte
+ abbrind : byte
+;;
+
+const load = {file
+ var nisgmt
+ var nisstd
+ var nleap
+ var ntime
+ var ntype
+ var nchar
+ var i
+ var f
+ var p
+
+ /* check magic */
+ p = std.slurp(file)
+ if !std.sleq(p[:4], "TZif")
+ -> 0 castto(zifile#)
+ ;;
+
+ /* skip to data */
+ p = p[20:]
+ (nisgmt, p) = fetchbe32(p)
+ (nisstd, p) = fetchbe32(p)
+ (nleap, p) = fetchbe32(p)
+ (ntime, p) = fetchbe32(p)
+ (ntype, p) = fetchbe32(p)
+ (nchar, p) = fetchbe32(p)
+
+
+ f = std.alloc()
+ f.time = std.slalloc(ntime castto(std.size))
+ for i = 0; i < ntime; i++
+ (f.time[i], p) = fetchbe32(p)
+ ;;
+
+ f.timetype = std.slalloc(ntime castto(std.size))
+ for i = 0; i < ntime; i++
+ (f.timetype[i], p) = fetchbe8(p)
+ ;;
+
+ f.ttinfo = std.slalloc(ntype castto(std.size))
+ for i = 0; i < ntype; i++
+ p = fetchttinfo(p, &f.ttinfo[i])
+ ;;
+
+ f.abbrev = std.slalloc(nchar castto(std.size))
+ for i = 0; i < nchar; i++
+ (f.abbrev[i], p) = fetchbe8(p)
+ ;;
+
+ f.leap = std.slalloc(nleap castto(std.size))
+ for i = 0; i < nleap; i++
+ (f.leap[i][0], p) = fetchbe32(p)
+ (f.leap[i][1], p) = fetchbe32(p)
+ ;;
+
+ f.isstd = std.slalloc(nisstd castto(std.size))
+ for i = 0; i < nisstd; i++
+ (f.isstd[i], p) = fetchbe8(p)
+ ;;
+
+ f.isgmt = std.slalloc(nisgmt castto(std.size))
+ for i = 0; i < nisgmt; i++
+ (f.isgmt[i], p) = fetchbe8(p)
+ ;;
+
+
+ -> f
+}
+
+const fetchbe32 = {sl
+ var v
+
+ std.assert(sl.len >= 4, "Slice too small to fetch int32 from")
+ v = (sl[0] castto(int32)) << 24 | \
+ (sl[1] castto(int32)) << 16 | \
+ (sl[2] castto(int32)) << 8 | \
+ (sl[3] castto(int32)) << 0
+ -> (v, sl[4:])
+}
+
+const fetchbe8 = {sl
+ var v
+
+ std.assert(sl.len >= 1, "Slice too small to fetch int8 from")
+ v = sl[0]
+ -> (v, sl[1:])
+}
+
+
+const fetchttinfo = {sl, dst : ttinfo#
+ (dst.gmtoff, sl) = fetchbe32(sl)
+ (dst.isdst, sl) = fetchbe8(sl)
+ (dst.abbrind, sl) = fetchbe8(sl)
+ -> sl
+}
+