unzip_nacl.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. // Copyright 2009 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. // Small in-memory unzip implementation.
  5. // A simplified copy of the pre-Go 1 compress/flate/inflate.go
  6. // and a modified copy of the zip reader in package time.
  7. // (The one in package time does not support decompression; this one does.)
  8. package unix
  9. const (
  10. maxCodeLen = 16 // max length of Huffman code
  11. maxHist = 32768 // max history required
  12. maxLit = 286
  13. maxDist = 32
  14. numCodes = 19 // number of codes in Huffman meta-code
  15. )
  16. type decompressor struct {
  17. in string // compressed input
  18. out []byte // uncompressed output
  19. b uint32 // input bits, at top of b
  20. nb uint
  21. err bool // invalid input
  22. eof bool // reached EOF
  23. h1, h2 huffmanDecoder // decoders for literal/length, distance
  24. bits [maxLit + maxDist]int // lengths defining Huffman codes
  25. codebits [numCodes]int
  26. }
  27. func (f *decompressor) nextBlock() {
  28. for f.nb < 1+2 {
  29. if f.moreBits(); f.err {
  30. return
  31. }
  32. }
  33. f.eof = f.b&1 == 1
  34. f.b >>= 1
  35. typ := f.b & 3
  36. f.b >>= 2
  37. f.nb -= 1 + 2
  38. switch typ {
  39. case 0:
  40. f.dataBlock()
  41. case 1:
  42. // compressed, fixed Huffman tables
  43. f.huffmanBlock(&fixedHuffmanDecoder, nil)
  44. case 2:
  45. // compressed, dynamic Huffman tables
  46. if f.readHuffman(); f.err {
  47. break
  48. }
  49. f.huffmanBlock(&f.h1, &f.h2)
  50. default:
  51. // 3 is reserved.
  52. f.err = true
  53. }
  54. }
  55. // RFC 1951 section 3.2.7.
  56. // Compression with dynamic Huffman codes
  57. var codeOrder = [...]int{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}
  58. func (f *decompressor) readHuffman() {
  59. // HLIT[5], HDIST[5], HCLEN[4].
  60. for f.nb < 5+5+4 {
  61. if f.moreBits(); f.err {
  62. return
  63. }
  64. }
  65. nlit := int(f.b&0x1F) + 257
  66. f.b >>= 5
  67. ndist := int(f.b&0x1F) + 1
  68. f.b >>= 5
  69. nclen := int(f.b&0xF) + 4
  70. f.b >>= 4
  71. f.nb -= 5 + 5 + 4
  72. // (HCLEN+4)*3 bits: code lengths in the magic codeOrder order.
  73. for i := 0; i < nclen; i++ {
  74. for f.nb < 3 {
  75. if f.moreBits(); f.err {
  76. return
  77. }
  78. }
  79. f.codebits[codeOrder[i]] = int(f.b & 0x7)
  80. f.b >>= 3
  81. f.nb -= 3
  82. }
  83. for i := nclen; i < len(codeOrder); i++ {
  84. f.codebits[codeOrder[i]] = 0
  85. }
  86. if !f.h1.init(f.codebits[0:]) {
  87. f.err = true
  88. return
  89. }
  90. // HLIT + 257 code lengths, HDIST + 1 code lengths,
  91. // using the code length Huffman code.
  92. for i, n := 0, nlit+ndist; i < n; {
  93. x := f.huffSym(&f.h1)
  94. if f.err {
  95. return
  96. }
  97. if x < 16 {
  98. // Actual length.
  99. f.bits[i] = x
  100. i++
  101. continue
  102. }
  103. // Repeat previous length or zero.
  104. var rep int
  105. var nb uint
  106. var b int
  107. switch x {
  108. default:
  109. f.err = true
  110. return
  111. case 16:
  112. rep = 3
  113. nb = 2
  114. if i == 0 {
  115. f.err = true
  116. return
  117. }
  118. b = f.bits[i-1]
  119. case 17:
  120. rep = 3
  121. nb = 3
  122. b = 0
  123. case 18:
  124. rep = 11
  125. nb = 7
  126. b = 0
  127. }
  128. for f.nb < nb {
  129. if f.moreBits(); f.err {
  130. return
  131. }
  132. }
  133. rep += int(f.b & uint32(1<<nb-1))
  134. f.b >>= nb
  135. f.nb -= nb
  136. if i+rep > n {
  137. f.err = true
  138. return
  139. }
  140. for j := 0; j < rep; j++ {
  141. f.bits[i] = b
  142. i++
  143. }
  144. }
  145. if !f.h1.init(f.bits[0:nlit]) || !f.h2.init(f.bits[nlit:nlit+ndist]) {
  146. f.err = true
  147. return
  148. }
  149. }
  150. // Decode a single Huffman block from f.
  151. // hl and hd are the Huffman states for the lit/length values
  152. // and the distance values, respectively. If hd == nil, using the
  153. // fixed distance encoding associated with fixed Huffman blocks.
  154. func (f *decompressor) huffmanBlock(hl, hd *huffmanDecoder) {
  155. for {
  156. v := f.huffSym(hl)
  157. if f.err {
  158. return
  159. }
  160. var n uint // number of bits extra
  161. var length int
  162. switch {
  163. case v < 256:
  164. f.out = append(f.out, byte(v))
  165. continue
  166. case v == 256:
  167. // Done with huffman block; read next block.
  168. return
  169. // otherwise, reference to older data
  170. case v < 265:
  171. length = v - (257 - 3)
  172. n = 0
  173. case v < 269:
  174. length = v*2 - (265*2 - 11)
  175. n = 1
  176. case v < 273:
  177. length = v*4 - (269*4 - 19)
  178. n = 2
  179. case v < 277:
  180. length = v*8 - (273*8 - 35)
  181. n = 3
  182. case v < 281:
  183. length = v*16 - (277*16 - 67)
  184. n = 4
  185. case v < 285:
  186. length = v*32 - (281*32 - 131)
  187. n = 5
  188. default:
  189. length = 258
  190. n = 0
  191. }
  192. if n > 0 {
  193. for f.nb < n {
  194. if f.moreBits(); f.err {
  195. return
  196. }
  197. }
  198. length += int(f.b & uint32(1<<n-1))
  199. f.b >>= n
  200. f.nb -= n
  201. }
  202. var dist int
  203. if hd == nil {
  204. for f.nb < 5 {
  205. if f.moreBits(); f.err {
  206. return
  207. }
  208. }
  209. dist = int(reverseByte[(f.b&0x1F)<<3])
  210. f.b >>= 5
  211. f.nb -= 5
  212. } else {
  213. if dist = f.huffSym(hd); f.err {
  214. return
  215. }
  216. }
  217. switch {
  218. case dist < 4:
  219. dist++
  220. case dist >= 30:
  221. f.err = true
  222. return
  223. default:
  224. nb := uint(dist-2) >> 1
  225. // have 1 bit in bottom of dist, need nb more.
  226. extra := (dist & 1) << nb
  227. for f.nb < nb {
  228. if f.moreBits(); f.err {
  229. return
  230. }
  231. }
  232. extra |= int(f.b & uint32(1<<nb-1))
  233. f.b >>= nb
  234. f.nb -= nb
  235. dist = 1<<(nb+1) + 1 + extra
  236. }
  237. // Copy [-dist:-dist+length] into output.
  238. // Encoding can be prescient, so no check on length.
  239. if dist > len(f.out) {
  240. f.err = true
  241. return
  242. }
  243. p := len(f.out) - dist
  244. for i := 0; i < length; i++ {
  245. f.out = append(f.out, f.out[p])
  246. p++
  247. }
  248. }
  249. }
  250. // Copy a single uncompressed data block from input to output.
  251. func (f *decompressor) dataBlock() {
  252. // Uncompressed.
  253. // Discard current half-byte.
  254. f.nb = 0
  255. f.b = 0
  256. if len(f.in) < 4 {
  257. f.err = true
  258. return
  259. }
  260. buf := f.in[:4]
  261. f.in = f.in[4:]
  262. n := int(buf[0]) | int(buf[1])<<8
  263. nn := int(buf[2]) | int(buf[3])<<8
  264. if uint16(nn) != uint16(^n) {
  265. f.err = true
  266. return
  267. }
  268. if len(f.in) < n {
  269. f.err = true
  270. return
  271. }
  272. f.out = append(f.out, f.in[:n]...)
  273. f.in = f.in[n:]
  274. }
  275. func (f *decompressor) moreBits() {
  276. if len(f.in) == 0 {
  277. f.err = true
  278. return
  279. }
  280. c := f.in[0]
  281. f.in = f.in[1:]
  282. f.b |= uint32(c) << f.nb
  283. f.nb += 8
  284. }
  285. // Read the next Huffman-encoded symbol from f according to h.
  286. func (f *decompressor) huffSym(h *huffmanDecoder) int {
  287. for n := uint(h.min); n <= uint(h.max); n++ {
  288. lim := h.limit[n]
  289. if lim == -1 {
  290. continue
  291. }
  292. for f.nb < n {
  293. if f.moreBits(); f.err {
  294. return 0
  295. }
  296. }
  297. v := int(f.b & uint32(1<<n-1))
  298. v <<= 16 - n
  299. v = int(reverseByte[v>>8]) | int(reverseByte[v&0xFF])<<8 // reverse bits
  300. if v <= lim {
  301. f.b >>= n
  302. f.nb -= n
  303. return h.codes[v-h.base[n]]
  304. }
  305. }
  306. f.err = true
  307. return 0
  308. }
  309. var reverseByte = [256]byte{
  310. 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
  311. 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
  312. 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
  313. 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
  314. 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
  315. 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
  316. 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
  317. 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
  318. 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
  319. 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
  320. 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
  321. 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
  322. 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
  323. 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
  324. 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
  325. 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
  326. 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
  327. 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
  328. 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
  329. 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
  330. 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
  331. 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
  332. 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
  333. 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
  334. 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
  335. 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
  336. 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
  337. 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
  338. 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
  339. 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
  340. 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
  341. 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
  342. }
  343. // Hard-coded Huffman tables for DEFLATE algorithm.
  344. // See RFC 1951, section 3.2.6.
  345. var fixedHuffmanDecoder = huffmanDecoder{
  346. 7, 9,
  347. [maxCodeLen + 1]int{7: 23, 199, 511},
  348. [maxCodeLen + 1]int{7: 0, 24, 224},
  349. []int{
  350. // length 7: 256-279
  351. 256, 257, 258, 259, 260, 261, 262,
  352. 263, 264, 265, 266, 267, 268, 269,
  353. 270, 271, 272, 273, 274, 275, 276,
  354. 277, 278, 279,
  355. // length 8: 0-143
  356. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
  357. 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
  358. 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  359. 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
  360. 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
  361. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
  362. 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
  363. 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
  364. 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
  365. 92, 93, 94, 95, 96, 97, 98, 99, 100,
  366. 101, 102, 103, 104, 105, 106, 107, 108,
  367. 109, 110, 111, 112, 113, 114, 115, 116,
  368. 117, 118, 119, 120, 121, 122, 123, 124,
  369. 125, 126, 127, 128, 129, 130, 131, 132,
  370. 133, 134, 135, 136, 137, 138, 139, 140,
  371. 141, 142, 143,
  372. // length 8: 280-287
  373. 280, 281, 282, 283, 284, 285, 286, 287,
  374. // length 9: 144-255
  375. 144, 145, 146, 147, 148, 149, 150, 151,
  376. 152, 153, 154, 155, 156, 157, 158, 159,
  377. 160, 161, 162, 163, 164, 165, 166, 167,
  378. 168, 169, 170, 171, 172, 173, 174, 175,
  379. 176, 177, 178, 179, 180, 181, 182, 183,
  380. 184, 185, 186, 187, 188, 189, 190, 191,
  381. 192, 193, 194, 195, 196, 197, 198, 199,
  382. 200, 201, 202, 203, 204, 205, 206, 207,
  383. 208, 209, 210, 211, 212, 213, 214, 215,
  384. 216, 217, 218, 219, 220, 221, 222, 223,
  385. 224, 225, 226, 227, 228, 229, 230, 231,
  386. 232, 233, 234, 235, 236, 237, 238, 239,
  387. 240, 241, 242, 243, 244, 245, 246, 247,
  388. 248, 249, 250, 251, 252, 253, 254, 255,
  389. },
  390. }
  391. // Huffman decoder is based on
  392. // J. Brian Connell, ``A Huffman-Shannon-Fano Code,''
  393. // Proceedings of the IEEE, 61(7) (July 1973), pp 1046-1047.
  394. type huffmanDecoder struct {
  395. // min, max code length
  396. min, max int
  397. // limit[i] = largest code word of length i
  398. // Given code v of length n,
  399. // need more bits if v > limit[n].
  400. limit [maxCodeLen + 1]int
  401. // base[i] = smallest code word of length i - seq number
  402. base [maxCodeLen + 1]int
  403. // codes[seq number] = output code.
  404. // Given code v of length n, value is
  405. // codes[v - base[n]].
  406. codes []int
  407. }
  408. // Initialize Huffman decoding tables from array of code lengths.
  409. func (h *huffmanDecoder) init(bits []int) bool {
  410. // Count number of codes of each length,
  411. // compute min and max length.
  412. var count [maxCodeLen + 1]int
  413. var min, max int
  414. for _, n := range bits {
  415. if n == 0 {
  416. continue
  417. }
  418. if min == 0 || n < min {
  419. min = n
  420. }
  421. if n > max {
  422. max = n
  423. }
  424. count[n]++
  425. }
  426. if max == 0 {
  427. return false
  428. }
  429. h.min = min
  430. h.max = max
  431. // For each code range, compute
  432. // nextcode (first code of that length),
  433. // limit (last code of that length), and
  434. // base (offset from first code to sequence number).
  435. code := 0
  436. seq := 0
  437. var nextcode [maxCodeLen]int
  438. for i := min; i <= max; i++ {
  439. n := count[i]
  440. nextcode[i] = code
  441. h.base[i] = code - seq
  442. code += n
  443. seq += n
  444. h.limit[i] = code - 1
  445. code <<= 1
  446. }
  447. // Make array mapping sequence numbers to codes.
  448. if len(h.codes) < len(bits) {
  449. h.codes = make([]int, len(bits))
  450. }
  451. for i, n := range bits {
  452. if n == 0 {
  453. continue
  454. }
  455. code := nextcode[n]
  456. nextcode[n]++
  457. seq := code - h.base[n]
  458. h.codes[seq] = i
  459. }
  460. return true
  461. }
  462. func inflate(in string) (out []byte) {
  463. var d decompressor
  464. d.in = in
  465. for !d.err && !d.eof {
  466. d.nextBlock()
  467. }
  468. if len(d.in) != 0 {
  469. println("fs unzip: junk at end of compressed data")
  470. return nil
  471. }
  472. return d.out
  473. }
  474. // get4 returns the little-endian 32-bit value in b.
  475. func zget4(b string) int {
  476. if len(b) < 4 {
  477. return 0
  478. }
  479. return int(b[0]) | int(b[1])<<8 | int(b[2])<<16 | int(b[3])<<24
  480. }
  481. // get2 returns the little-endian 16-bit value in b.
  482. func zget2(b string) int {
  483. if len(b) < 2 {
  484. return 0
  485. }
  486. return int(b[0]) | int(b[1])<<8
  487. }
  488. func unzip(data string) {
  489. const (
  490. zecheader = 0x06054b50
  491. zcheader = 0x02014b50
  492. ztailsize = 22
  493. zheadersize = 30
  494. zheader = 0x04034b50
  495. )
  496. buf := data[len(data)-ztailsize:]
  497. n := zget2(buf[10:])
  498. size := zget4(buf[12:])
  499. off := zget4(buf[16:])
  500. hdr := data[off : off+size]
  501. for i := 0; i < n; i++ {
  502. // zip entry layout:
  503. // 0 magic[4]
  504. // 4 madevers[1]
  505. // 5 madeos[1]
  506. // 6 extvers[1]
  507. // 7 extos[1]
  508. // 8 flags[2]
  509. // 10 meth[2]
  510. // 12 modtime[2]
  511. // 14 moddate[2]
  512. // 16 crc[4]
  513. // 20 csize[4]
  514. // 24 uncsize[4]
  515. // 28 namelen[2]
  516. // 30 xlen[2]
  517. // 32 fclen[2]
  518. // 34 disknum[2]
  519. // 36 iattr[2]
  520. // 38 eattr[4]
  521. // 42 off[4]
  522. // 46 name[namelen]
  523. // 46+namelen+xlen+fclen - next header
  524. //
  525. if zget4(hdr) != zcheader {
  526. println("fs unzip: bad magic")
  527. break
  528. }
  529. meth := zget2(hdr[10:])
  530. mtime := zget2(hdr[12:])
  531. mdate := zget2(hdr[14:])
  532. csize := zget4(hdr[20:])
  533. size := zget4(hdr[24:])
  534. namelen := zget2(hdr[28:])
  535. xlen := zget2(hdr[30:])
  536. fclen := zget2(hdr[32:])
  537. xattr := uint32(zget4(hdr[38:])) >> 16
  538. off := zget4(hdr[42:])
  539. name := hdr[46 : 46+namelen]
  540. hdr = hdr[46+namelen+xlen+fclen:]
  541. // zip per-file header layout:
  542. // 0 magic[4]
  543. // 4 extvers[1]
  544. // 5 extos[1]
  545. // 6 flags[2]
  546. // 8 meth[2]
  547. // 10 modtime[2]
  548. // 12 moddate[2]
  549. // 14 crc[4]
  550. // 18 csize[4]
  551. // 22 uncsize[4]
  552. // 26 namelen[2]
  553. // 28 xlen[2]
  554. // 30 name[namelen]
  555. // 30+namelen+xlen - file data
  556. //
  557. buf := data[off : off+zheadersize+namelen]
  558. if zget4(buf) != zheader ||
  559. zget2(buf[8:]) != meth ||
  560. zget2(buf[26:]) != namelen ||
  561. buf[30:30+namelen] != name {
  562. println("fs unzip: inconsistent zip file")
  563. return
  564. }
  565. xlen = zget2(buf[28:])
  566. off += zheadersize + namelen + xlen
  567. var fdata []byte
  568. switch meth {
  569. case 0:
  570. // buf is uncompressed
  571. buf = data[off : off+size]
  572. fdata = []byte(buf)
  573. case 8:
  574. // buf is deflate-compressed
  575. buf = data[off : off+csize]
  576. fdata = inflate(buf)
  577. if len(fdata) != size {
  578. println("fs unzip: inconsistent size in zip file")
  579. return
  580. }
  581. }
  582. if xattr&S_IFMT == 0 {
  583. if xattr&0777 == 0 {
  584. xattr |= 0666
  585. }
  586. if len(name) > 0 && name[len(name)-1] == '/' {
  587. xattr |= S_IFDIR
  588. xattr |= 0111
  589. } else {
  590. xattr |= S_IFREG
  591. }
  592. }
  593. if err := create(name, xattr, zipToTime(mdate, mtime), fdata); err != nil {
  594. print("fs unzip: create ", name, ": ", err.Error(), "\n")
  595. }
  596. }
  597. chdirEnv()
  598. }
  599. func zipToTime(date, time int) int64 {
  600. dd := date & 0x1f
  601. mm := date >> 5 & 0xf
  602. yy := date >> 9 // since 1980
  603. sec := int64(315532800) // jan 1 1980
  604. sec += int64(yy) * 365 * 86400
  605. sec += int64(yy) / 4 * 86400
  606. if yy%4 > 0 || mm >= 3 {
  607. sec += 86400
  608. }
  609. sec += int64(daysBeforeMonth[mm]) * 86400
  610. sec += int64(dd-1) * 86400
  611. h := time >> 11
  612. m := time >> 5 & 0x3F
  613. s := time & 0x1f * 2
  614. sec += int64(h*3600 + m*60 + s)
  615. return sec
  616. }
  617. var daysBeforeMonth = [...]int32{
  618. 0,
  619. 0,
  620. 31,
  621. 31 + 28,
  622. 31 + 28 + 31,
  623. 31 + 28 + 31 + 30,
  624. 31 + 28 + 31 + 30 + 31,
  625. 31 + 28 + 31 + 30 + 31 + 30,
  626. 31 + 28 + 31 + 30 + 31 + 30 + 31,
  627. 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
  628. 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
  629. 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
  630. 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
  631. 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31,
  632. }