timestamp.go (1933B)
1 package msgpack 2 3 import ( 4 "fmt" 5 "time" 6 ) 7 8 type Timestamp struct { 9 seconds int64 10 nanoseconds int 11 } 12 13 var _ Extension = (*Timestamp)(nil) 14 15 func NewTimestamp(t time.Time) *Timestamp { 16 return &Timestamp{ 17 seconds: t.Unix(), 18 nanoseconds: t.Nanosecond(), 19 } 20 } 21 22 func (t *Timestamp) Time() time.Time { 23 return time.Unix(t.seconds, int64(t.nanoseconds)).UTC() 24 } 25 26 func (t *Timestamp) EncodeMsgpackExt(e *Encoder) { 27 if t.seconds>>34 == 0 { 28 if t.nanoseconds == 0 && t.seconds>>32 == 0 { 29 t.serialize32(e) 30 } else { 31 t.serialize64(e) 32 } 33 } else { 34 t.serialize96(e) 35 } 36 } 37 38 func (t *Timestamp) DecodeMsgpackExt(d *Decoder, typ int8, size int) error { 39 if typ != t.Type() { 40 return fmt.Errorf("encoding/msgpack: timestamp: invalid type: %d", typ) 41 } 42 switch size { 43 case 4: 44 s, err := d.deserialize32() 45 if err != nil { 46 return err 47 } 48 *t = Timestamp{ 49 seconds: int64(s), 50 } 51 case 8: 52 v, err := d.deserialize64() 53 if err != nil { 54 return err 55 } 56 *t = Timestamp{ 57 nanoseconds: int(v >> 34), 58 seconds: int64(v & 0x00000003ffffffff), 59 } 60 case 12: 61 ns, err := d.deserialize32() 62 if err != nil { 63 return err 64 } 65 s, err := d.deserialize64() 66 if err != nil { 67 return err 68 } 69 *t = Timestamp{ 70 nanoseconds: int(ns), 71 seconds: int64(s), 72 } 73 default: 74 return fmt.Errorf("encoding/msgpack: timestamp: invalid size: %d", size) 75 } 76 return nil 77 } 78 79 func (t *Timestamp) Type() int8 { 80 return -1 81 } 82 83 func (t *Timestamp) Size() int { 84 if t.seconds>>34 == 0 { 85 if t.nanoseconds == 0 && t.seconds>>32 == 0 { 86 return 4 87 } else { 88 return 8 89 } 90 } else { 91 return 12 92 } 93 } 94 95 func (t *Timestamp) serialize32(e *Encoder) { 96 e.serialize32(uint32(t.seconds)) 97 } 98 99 func (t *Timestamp) serialize64(e *Encoder) { 100 e.serialize64(uint64(t.nanoseconds<<34) | uint64(t.seconds&0x3ffffffff)) 101 } 102 103 func (t *Timestamp) serialize96(e *Encoder) { 104 e.serialize32(uint32(t.nanoseconds)) 105 e.serialize64(uint64(t.seconds)) 106 }