ducky/devices

Paddy 2015-11-15 Parent:b6494e1a499e

6:e0bf06577ba5 Go to Latest

ducky/devices/vendor/code.google.com/p/go-uuid/uuid/time.go

Ignore coverage output. Add a .hgignore file to ignore the output file that tracks our test coverage.

History
paddy@0 1 // Copyright 2014 Google Inc. All rights reserved.
paddy@0 2 // Use of this source code is governed by a BSD-style
paddy@0 3 // license that can be found in the LICENSE file.
paddy@0 4
paddy@0 5 package uuid
paddy@0 6
paddy@0 7 import (
paddy@0 8 "encoding/binary"
paddy@0 9 "sync"
paddy@0 10 "time"
paddy@0 11 )
paddy@0 12
paddy@0 13 // A Time represents a time as the number of 100's of nanoseconds since 15 Oct
paddy@0 14 // 1582.
paddy@0 15 type Time int64
paddy@0 16
paddy@0 17 const (
paddy@0 18 lillian = 2299160 // Julian day of 15 Oct 1582
paddy@0 19 unix = 2440587 // Julian day of 1 Jan 1970
paddy@0 20 epoch = unix - lillian // Days between epochs
paddy@0 21 g1582 = epoch * 86400 // seconds between epochs
paddy@0 22 g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs
paddy@0 23 )
paddy@0 24
paddy@0 25 var (
paddy@0 26 mu sync.Mutex
paddy@0 27 lasttime uint64 // last time we returned
paddy@0 28 clock_seq uint16 // clock sequence for this run
paddy@0 29
paddy@0 30 timeNow = time.Now // for testing
paddy@0 31 )
paddy@0 32
paddy@0 33 // UnixTime converts t the number of seconds and nanoseconds using the Unix
paddy@0 34 // epoch of 1 Jan 1970.
paddy@0 35 func (t Time) UnixTime() (sec, nsec int64) {
paddy@0 36 sec = int64(t - g1582ns100)
paddy@0 37 nsec = (sec % 10000000) * 100
paddy@0 38 sec /= 10000000
paddy@0 39 return sec, nsec
paddy@0 40 }
paddy@0 41
paddy@0 42 // GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and
paddy@0 43 // clock sequence as well as adjusting the clock sequence as needed. An error
paddy@0 44 // is returned if the current time cannot be determined.
paddy@0 45 func GetTime() (Time, uint16, error) {
paddy@0 46 defer mu.Unlock()
paddy@0 47 mu.Lock()
paddy@0 48 return getTime()
paddy@0 49 }
paddy@0 50
paddy@0 51 func getTime() (Time, uint16, error) {
paddy@0 52 t := timeNow()
paddy@0 53
paddy@0 54 // If we don't have a clock sequence already, set one.
paddy@0 55 if clock_seq == 0 {
paddy@0 56 setClockSequence(-1)
paddy@0 57 }
paddy@0 58 now := uint64(t.UnixNano()/100) + g1582ns100
paddy@0 59
paddy@0 60 // If time has gone backwards with this clock sequence then we
paddy@0 61 // increment the clock sequence
paddy@0 62 if now <= lasttime {
paddy@0 63 clock_seq = ((clock_seq + 1) & 0x3fff) | 0x8000
paddy@0 64 }
paddy@0 65 lasttime = now
paddy@0 66 return Time(now), clock_seq, nil
paddy@0 67 }
paddy@0 68
paddy@0 69 // ClockSequence returns the current clock sequence, generating one if not
paddy@0 70 // already set. The clock sequence is only used for Version 1 UUIDs.
paddy@0 71 //
paddy@0 72 // The uuid package does not use global static storage for the clock sequence or
paddy@0 73 // the last time a UUID was generated. Unless SetClockSequence a new random
paddy@0 74 // clock sequence is generated the first time a clock sequence is requested by
paddy@0 75 // ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) sequence is generated
paddy@0 76 // for
paddy@0 77 func ClockSequence() int {
paddy@0 78 defer mu.Unlock()
paddy@0 79 mu.Lock()
paddy@0 80 return clockSequence()
paddy@0 81 }
paddy@0 82
paddy@0 83 func clockSequence() int {
paddy@0 84 if clock_seq == 0 {
paddy@0 85 setClockSequence(-1)
paddy@0 86 }
paddy@0 87 return int(clock_seq & 0x3fff)
paddy@0 88 }
paddy@0 89
paddy@0 90 // SetClockSeq sets the clock sequence to the lower 14 bits of seq. Setting to
paddy@0 91 // -1 causes a new sequence to be generated.
paddy@0 92 func SetClockSequence(seq int) {
paddy@0 93 defer mu.Unlock()
paddy@0 94 mu.Lock()
paddy@0 95 setClockSequence(seq)
paddy@0 96 }
paddy@0 97
paddy@0 98 func setClockSequence(seq int) {
paddy@0 99 if seq == -1 {
paddy@0 100 var b [2]byte
paddy@0 101 randomBits(b[:]) // clock sequence
paddy@0 102 seq = int(b[0])<<8 | int(b[1])
paddy@0 103 }
paddy@0 104 old_seq := clock_seq
paddy@0 105 clock_seq = uint16(seq&0x3fff) | 0x8000 // Set our variant
paddy@0 106 if old_seq != clock_seq {
paddy@0 107 lasttime = 0
paddy@0 108 }
paddy@0 109 }
paddy@0 110
paddy@0 111 // Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in
paddy@0 112 // uuid. It returns false if uuid is not valid. The time is only well defined
paddy@0 113 // for version 1 and 2 UUIDs.
paddy@0 114 func (uuid UUID) Time() (Time, bool) {
paddy@0 115 if len(uuid) != 16 {
paddy@0 116 return 0, false
paddy@0 117 }
paddy@0 118 time := int64(binary.BigEndian.Uint32(uuid[0:4]))
paddy@0 119 time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32
paddy@0 120 time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48
paddy@0 121 return Time(time), true
paddy@0 122 }
paddy@0 123
paddy@0 124 // ClockSequence returns the clock sequence encoded in uuid. It returns false
paddy@0 125 // if uuid is not valid. The clock sequence is only well defined for version 1
paddy@0 126 // and 2 UUIDs.
paddy@0 127 func (uuid UUID) ClockSequence() (int, bool) {
paddy@0 128 if len(uuid) != 16 {
paddy@0 129 return 0, false
paddy@0 130 }
paddy@0 131 return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff, true
paddy@0 132 }