msgpack-go

Message Pack Encoder/Decoder for Golang
git clone git://git.lair.cx/msgpack-go
Log | Files | Refs | LICENSE

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 }