modernc.org/ql@v1.4.7/blob.go (about)

     1  // Copyright 2014 The ql 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  
     5  package ql // import "modernc.org/ql"
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/gob"
    10  	"math/big"
    11  	"sync"
    12  	"time"
    13  )
    14  
    15  const shortBlob = 256 // bytes
    16  
    17  var (
    18  	gobInitDuration = time.Duration(278)
    19  	gobInitInt      = big.NewInt(42)
    20  	gobInitRat      = big.NewRat(355, 113)
    21  	gobInitTime     time.Time
    22  )
    23  
    24  func init() {
    25  	var err error
    26  	if gobInitTime, err = time.ParseInLocation(
    27  		"Jan 2, 2006 at 3:04pm (MST)",
    28  		"Jul 9, 2012 at 5:02am (CEST)",
    29  		time.FixedZone("XYZ", 1234),
    30  	); err != nil {
    31  		panic(err)
    32  	}
    33  	newGobCoder()
    34  }
    35  
    36  type gobCoder struct {
    37  	buf bytes.Buffer
    38  	dec *gob.Decoder
    39  	enc *gob.Encoder
    40  	mu  sync.Mutex
    41  }
    42  
    43  func newGobCoder() (g *gobCoder) {
    44  	g = &gobCoder{}
    45  	g.enc = gob.NewEncoder(&g.buf)
    46  	if err := g.enc.Encode(gobInitInt); err != nil {
    47  		panic(err)
    48  	}
    49  
    50  	if err := g.enc.Encode(gobInitRat); err != nil {
    51  		panic(err)
    52  	}
    53  
    54  	if err := g.enc.Encode(gobInitTime); err != nil {
    55  		panic(err)
    56  	}
    57  
    58  	if err := g.enc.Encode(gobInitDuration); err != nil {
    59  		panic(err)
    60  	}
    61  
    62  	g.dec = gob.NewDecoder(&g.buf)
    63  	i := big.NewInt(0)
    64  	if err := g.dec.Decode(i); err != nil {
    65  		panic(err)
    66  	}
    67  
    68  	r := big.NewRat(3, 5)
    69  	if err := g.dec.Decode(r); err != nil {
    70  		panic(err)
    71  	}
    72  
    73  	t := time.Now()
    74  	if err := g.dec.Decode(&t); err != nil {
    75  		panic(err)
    76  	}
    77  
    78  	var d time.Duration
    79  	if err := g.dec.Decode(&d); err != nil {
    80  		panic(err)
    81  	}
    82  
    83  	return
    84  }
    85  
    86  func isBlobType(v interface{}) (bool, Type) {
    87  	switch v.(type) {
    88  	case []byte:
    89  		return true, Blob
    90  	case *big.Int:
    91  		return true, BigInt
    92  	case *big.Rat:
    93  		return true, BigRat
    94  	case time.Time:
    95  		return true, Time
    96  	case time.Duration:
    97  		return true, Duration
    98  	default:
    99  		return false, -1
   100  	}
   101  }
   102  
   103  func (g *gobCoder) encode(v interface{}) (b []byte, err error) {
   104  	g.mu.Lock()
   105  	defer g.mu.Unlock()
   106  
   107  	g.buf.Reset()
   108  	switch x := v.(type) {
   109  	case []byte:
   110  		return x, nil
   111  	case *big.Int:
   112  		err = g.enc.Encode(x)
   113  	case *big.Rat:
   114  		err = g.enc.Encode(x)
   115  	case time.Time:
   116  		err = g.enc.Encode(x)
   117  	case time.Duration:
   118  		err = g.enc.Encode(int64(x))
   119  	default:
   120  		panic("internal error 002")
   121  	}
   122  	b = g.buf.Bytes()
   123  	return
   124  }
   125  
   126  func (g *gobCoder) decode(b []byte, typ int) (v interface{}, err error) {
   127  	g.mu.Lock()
   128  	defer g.mu.Unlock()
   129  
   130  	g.buf.Reset()
   131  	g.buf.Write(b)
   132  	switch typ {
   133  	case qBlob:
   134  		return b, nil
   135  	case qBigInt:
   136  		x := big.NewInt(0)
   137  		err = g.dec.Decode(&x)
   138  		v = x
   139  	case qBigRat:
   140  		x := big.NewRat(1, 1)
   141  		err = g.dec.Decode(&x)
   142  		v = x
   143  	case qTime:
   144  		var x time.Time
   145  		err = g.dec.Decode(&x)
   146  		v = x
   147  	case qDuration:
   148  		var x int64
   149  		err = g.dec.Decode(&x)
   150  		v = time.Duration(x)
   151  	default:
   152  		panic("internal error 003")
   153  	}
   154  	return
   155  }