update mgo dependency

This commit is contained in:
Ian Kent 2016-09-04 19:28:08 +01:00
parent b026d2a04a
commit d6585029d6
6 changed files with 39 additions and 756 deletions

23
vendor/gopkg.in/mgo.v2/bson/bson.go generated vendored
View file

@ -38,7 +38,6 @@ import (
"crypto/rand" "crypto/rand"
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -205,7 +204,6 @@ func readRandomUint32() uint32 {
// machineId stores machine id generated once and used in subsequent calls // machineId stores machine id generated once and used in subsequent calls
// to NewObjectId function. // to NewObjectId function.
var machineId = readMachineId() var machineId = readMachineId()
var processId = os.Getpid()
// readMachineId generates and returns a machine id. // readMachineId generates and returns a machine id.
// If this function fails to get the hostname it will cause a runtime error. // If this function fails to get the hostname it will cause a runtime error.
@ -236,8 +234,9 @@ func NewObjectId() ObjectId {
b[5] = machineId[1] b[5] = machineId[1]
b[6] = machineId[2] b[6] = machineId[2]
// Pid, 2 bytes, specs don't specify endianness, but we use big endian. // Pid, 2 bytes, specs don't specify endianness, but we use big endian.
b[7] = byte(processId >> 8) pid := os.Getpid()
b[8] = byte(processId) b[7] = byte(pid >> 8)
b[8] = byte(pid)
// Increment, 3 bytes, big endian // Increment, 3 bytes, big endian
i := atomic.AddUint32(&objectIdCounter, 1) i := atomic.AddUint32(&objectIdCounter, 1)
b[9] = byte(i >> 16) b[9] = byte(i >> 16)
@ -277,22 +276,6 @@ var nullBytes = []byte("null")
// UnmarshalJSON turns *bson.ObjectId into a json.Unmarshaller. // UnmarshalJSON turns *bson.ObjectId into a json.Unmarshaller.
func (id *ObjectId) UnmarshalJSON(data []byte) error { func (id *ObjectId) UnmarshalJSON(data []byte) error {
if len(data) > 0 && (data[0] == '{' || data[0] == 'O') {
var v struct {
Id json.RawMessage `json:"$oid"`
Func struct {
Id json.RawMessage
} `json:"$oidFunc"`
}
err := jdec(data, &v)
if err == nil {
if len(v.Id) > 0 {
data = []byte(v.Id)
} else {
data = []byte(v.Func.Id)
}
}
}
if len(data) == 2 && data[0] == '"' && data[1] == '"' || bytes.Equal(data, nullBytes) { if len(data) == 2 && data[0] == '"' && data[1] == '"' || bytes.Equal(data, nullBytes) {
*id = "" *id = ""
return nil return nil

View file

@ -1,310 +0,0 @@
// BSON library for Go
//
// Copyright (c) 2010-2012 - Gustavo Niemeyer <gustavo@niemeyer.net>
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package bson
import (
"fmt"
"strconv"
"strings"
)
// Decimal128 holds decimal128 BSON values.
type Decimal128 struct {
h, l uint64
}
func (d Decimal128) String() string {
var pos int // positive sign
var e int // exponent
var h, l uint64 // significand high/low
if d.h>>63&1 == 0 {
pos = 1
}
switch d.h >> 58 & (1<<5 - 1) {
case 0x1F:
return "NaN"
case 0x1E:
return "-Inf"[pos:]
}
l = d.l
if d.h>>61&3 == 3 {
// Bits: 1*sign 2*ignored 14*exponent 111*significand.
// Implicit 0b100 prefix in significand.
e = int(d.h>>47&(1<<14-1)) - 6176
//h = 4<<47 | d.h&(1<<47-1)
// Spec says all of these values are out of range.
h, l = 0, 0
} else {
// Bits: 1*sign 14*exponent 113*significand
e = int(d.h>>49&(1<<14-1)) - 6176
h = d.h & (1<<49 - 1)
}
// Would be handled by the logic below, but that's trivial and common.
if h == 0 && l == 0 && e == 0 {
return "-0"[pos:]
}
var repr [48]byte // Loop 5 times over 9 digits plus dot, negative sign, and leading zero.
var last = len(repr)
var i = len(repr)
var dot = len(repr) + e
var rem uint32
Loop:
for d9 := 0; d9 < 5; d9++ {
h, l, rem = divmod(h, l, 1e9)
for d1 := 0; d1 < 9; d1++ {
// Handle "-0.0", "0.00123400", "-1.00E-6", "1.050E+3", etc.
if i < len(repr) && (dot == i || l == 0 && h == 0 && rem > 0 && rem < 10 && (dot < i-6 || e > 0)) {
e += len(repr) - i
i--
repr[i] = '.'
last = i - 1
dot = len(repr) // Unmark.
}
c := '0' + byte(rem%10)
rem /= 10
i--
repr[i] = c
// Handle "0E+3", "1E+3", etc.
if l == 0 && h == 0 && rem == 0 && i == len(repr)-1 && (dot < i-5 || e > 0) {
last = i
break Loop
}
if c != '0' {
last = i
}
// Break early. Works without it, but why.
if dot > i && l == 0 && h == 0 && rem == 0 {
break Loop
}
}
}
repr[last-1] = '-'
last--
if e > 0 {
return string(repr[last+pos:]) + "E+" + strconv.Itoa(e)
}
if e < 0 {
return string(repr[last+pos:]) + "E" + strconv.Itoa(e)
}
return string(repr[last+pos:])
}
func divmod(h, l uint64, div uint32) (qh, ql uint64, rem uint32) {
div64 := uint64(div)
a := h >> 32
aq := a / div64
ar := a % div64
b := ar<<32 + h&(1<<32-1)
bq := b / div64
br := b % div64
c := br<<32 + l>>32
cq := c / div64
cr := c % div64
d := cr<<32 + l&(1<<32-1)
dq := d / div64
dr := d % div64
return (aq<<32 | bq), (cq<<32 | dq), uint32(dr)
}
var dNaN = Decimal128{0x1F << 58, 0}
var dPosInf = Decimal128{0x1E << 58, 0}
var dNegInf = Decimal128{0x3E << 58, 0}
func dErr(s string) (Decimal128, error) {
return dNaN, fmt.Errorf("cannot parse %q as a decimal128", s)
}
func ParseDecimal128(s string) (Decimal128, error) {
orig := s
if s == "" {
return dErr(orig)
}
neg := s[0] == '-'
if neg || s[0] == '+' {
s = s[1:]
}
if (len(s) == 3 || len(s) == 8) && (s[0] == 'N' || s[0] == 'n' || s[0] == 'I' || s[0] == 'i') {
if s == "NaN" || s == "nan" || strings.EqualFold(s, "nan") {
return dNaN, nil
}
if s == "Inf" || s == "inf" || strings.EqualFold(s, "inf") || strings.EqualFold(s, "infinity") {
if neg {
return dNegInf, nil
}
return dPosInf, nil
}
return dErr(orig)
}
var h, l uint64
var e int
var add, ovr uint32
var mul uint32 = 1
var dot = -1
var digits = 0
var i = 0
for i < len(s) {
c := s[i]
if mul == 1e9 {
h, l, ovr = muladd(h, l, mul, add)
mul, add = 1, 0
if ovr > 0 || h&((1<<15-1)<<49) > 0 {
return dErr(orig)
}
}
if c >= '0' && c <= '9' {
i++
if c > '0' || digits > 0 {
digits++
}
if digits > 34 {
if c == '0' {
// Exact rounding.
e++
continue
}
return dErr(orig)
}
mul *= 10
add *= 10
add += uint32(c - '0')
continue
}
if c == '.' {
i++
if dot >= 0 || i == 1 && len(s) == 1 {
return dErr(orig)
}
if i == len(s) {
break
}
if s[i] < '0' || s[i] > '9' || e > 0 {
return dErr(orig)
}
dot = i
continue
}
break
}
if i == 0 {
return dErr(orig)
}
if mul > 1 {
h, l, ovr = muladd(h, l, mul, add)
if ovr > 0 || h&((1<<15-1)<<49) > 0 {
return dErr(orig)
}
}
if dot >= 0 {
e += dot - i
}
if i+1 < len(s) && (s[i] == 'E' || s[i] == 'e') {
i++
eneg := s[i] == '-'
if eneg || s[i] == '+' {
i++
if i == len(s) {
return dErr(orig)
}
}
n := 0
for i < len(s) && n < 1e4 {
c := s[i]
i++
if c < '0' || c > '9' {
return dErr(orig)
}
n *= 10
n += int(c - '0')
}
if eneg {
n = -n
}
e += n
for e < -6176 {
// Subnormal.
var div uint32 = 1
for div < 1e9 && e < -6176 {
div *= 10
e++
}
var rem uint32
h, l, rem = divmod(h, l, div)
if rem > 0 {
return dErr(orig)
}
}
for e > 6111 {
// Clamped.
var mul uint32 = 1
for mul < 1e9 && e > 6111 {
mul *= 10
e--
}
h, l, ovr = muladd(h, l, mul, 0)
if ovr > 0 || h&((1<<15-1)<<49) > 0 {
return dErr(orig)
}
}
if e < -6176 || e > 6111 {
return dErr(orig)
}
}
if i < len(s) {
return dErr(orig)
}
h |= uint64(e+6176) & uint64(1<<14-1) << 49
if neg {
h |= 1 << 63
}
return Decimal128{h, l}, nil
}
func muladd(h, l uint64, mul uint32, add uint32) (resh, resl uint64, overflow uint32) {
mul64 := uint64(mul)
a := mul64 * (l & (1<<32 - 1))
b := a>>32 + mul64*(l>>32)
c := b>>32 + mul64*(h&(1<<32-1))
d := c>>32 + mul64*(h>>32)
a = a&(1<<32-1) + uint64(add)
b = b&(1<<32-1) + a>>32
c = c&(1<<32-1) + b>>32
d = d&(1<<32-1) + c>>32
return (d<<32 | c&(1<<32-1)), (b<<32 | a&(1<<32-1)), uint32(d >> 32)
}

View file

@ -539,11 +539,6 @@ func (d *decoder) readElemTo(out reflect.Value, kind byte) (good bool) {
in = MongoTimestamp(d.readInt64()) in = MongoTimestamp(d.readInt64())
case 0x12: // Int64 case 0x12: // Int64
in = d.readInt64() in = d.readInt64()
case 0x13: // Decimal128
in = Decimal128{
l: uint64(d.readInt64()),
h: uint64(d.readInt64()),
}
case 0x7F: // Max key case 0x7F: // Max key
in = MaxKey in = MaxKey
case 0xFF: // Min key case 0xFF: // Min key

View file

@ -247,7 +247,7 @@ func (e *encoder) addElemName(kind byte, name string) {
func (e *encoder) addElem(name string, v reflect.Value, minSize bool) { func (e *encoder) addElem(name string, v reflect.Value, minSize bool) {
if !v.IsValid() { if !v.IsValid() {
e.addElemName(0x0A, name) e.addElemName('\x0A', name)
return return
} }
@ -276,29 +276,29 @@ func (e *encoder) addElem(name string, v reflect.Value, minSize bool) {
panic("ObjectIDs must be exactly 12 bytes long (got " + panic("ObjectIDs must be exactly 12 bytes long (got " +
strconv.Itoa(len(s)) + ")") strconv.Itoa(len(s)) + ")")
} }
e.addElemName(0x07, name) e.addElemName('\x07', name)
e.addBytes([]byte(s)...) e.addBytes([]byte(s)...)
case typeSymbol: case typeSymbol:
e.addElemName(0x0E, name) e.addElemName('\x0E', name)
e.addStr(s) e.addStr(s)
case typeJSONNumber: case typeJSONNumber:
n := v.Interface().(json.Number) n := v.Interface().(json.Number)
if i, err := n.Int64(); err == nil { if i, err := n.Int64(); err == nil {
e.addElemName(0x12, name) e.addElemName('\x12', name)
e.addInt64(i) e.addInt64(i)
} else if f, err := n.Float64(); err == nil { } else if f, err := n.Float64(); err == nil {
e.addElemName(0x01, name) e.addElemName('\x01', name)
e.addFloat64(f) e.addFloat64(f)
} else { } else {
panic("failed to convert json.Number to a number: " + s) panic("failed to convert json.Number to a number: " + s)
} }
default: default:
e.addElemName(0x02, name) e.addElemName('\x02', name)
e.addStr(s) e.addStr(s)
} }
case reflect.Float32, reflect.Float64: case reflect.Float32, reflect.Float64:
e.addElemName(0x01, name) e.addElemName('\x01', name)
e.addFloat64(v.Float()) e.addFloat64(v.Float())
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
@ -306,40 +306,40 @@ func (e *encoder) addElem(name string, v reflect.Value, minSize bool) {
if int64(u) < 0 { if int64(u) < 0 {
panic("BSON has no uint64 type, and value is too large to fit correctly in an int64") panic("BSON has no uint64 type, and value is too large to fit correctly in an int64")
} else if u <= math.MaxInt32 && (minSize || v.Kind() <= reflect.Uint32) { } else if u <= math.MaxInt32 && (minSize || v.Kind() <= reflect.Uint32) {
e.addElemName(0x10, name) e.addElemName('\x10', name)
e.addInt32(int32(u)) e.addInt32(int32(u))
} else { } else {
e.addElemName(0x12, name) e.addElemName('\x12', name)
e.addInt64(int64(u)) e.addInt64(int64(u))
} }
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
switch v.Type() { switch v.Type() {
case typeMongoTimestamp: case typeMongoTimestamp:
e.addElemName(0x11, name) e.addElemName('\x11', name)
e.addInt64(v.Int()) e.addInt64(v.Int())
case typeOrderKey: case typeOrderKey:
if v.Int() == int64(MaxKey) { if v.Int() == int64(MaxKey) {
e.addElemName(0x7F, name) e.addElemName('\x7F', name)
} else { } else {
e.addElemName(0xFF, name) e.addElemName('\xFF', name)
} }
default: default:
i := v.Int() i := v.Int()
if (minSize || v.Type().Kind() != reflect.Int64) && i >= math.MinInt32 && i <= math.MaxInt32 { if (minSize || v.Type().Kind() != reflect.Int64) && i >= math.MinInt32 && i <= math.MaxInt32 {
// It fits into an int32, encode as such. // It fits into an int32, encode as such.
e.addElemName(0x10, name) e.addElemName('\x10', name)
e.addInt32(int32(i)) e.addInt32(int32(i))
} else { } else {
e.addElemName(0x12, name) e.addElemName('\x12', name)
e.addInt64(i) e.addInt64(i)
} }
} }
case reflect.Bool: case reflect.Bool:
e.addElemName(0x08, name) e.addElemName('\x08', name)
if v.Bool() { if v.Bool() {
e.addBytes(1) e.addBytes(1)
} else { } else {
@ -347,40 +347,40 @@ func (e *encoder) addElem(name string, v reflect.Value, minSize bool) {
} }
case reflect.Map: case reflect.Map:
e.addElemName(0x03, name) e.addElemName('\x03', name)
e.addDoc(v) e.addDoc(v)
case reflect.Slice: case reflect.Slice:
vt := v.Type() vt := v.Type()
et := vt.Elem() et := vt.Elem()
if et.Kind() == reflect.Uint8 { if et.Kind() == reflect.Uint8 {
e.addElemName(0x05, name) e.addElemName('\x05', name)
e.addBinary(0x00, v.Bytes()) e.addBinary('\x00', v.Bytes())
} else if et == typeDocElem || et == typeRawDocElem { } else if et == typeDocElem || et == typeRawDocElem {
e.addElemName(0x03, name) e.addElemName('\x03', name)
e.addDoc(v) e.addDoc(v)
} else { } else {
e.addElemName(0x04, name) e.addElemName('\x04', name)
e.addDoc(v) e.addDoc(v)
} }
case reflect.Array: case reflect.Array:
et := v.Type().Elem() et := v.Type().Elem()
if et.Kind() == reflect.Uint8 { if et.Kind() == reflect.Uint8 {
e.addElemName(0x05, name) e.addElemName('\x05', name)
if v.CanAddr() { if v.CanAddr() {
e.addBinary(0x00, v.Slice(0, v.Len()).Interface().([]byte)) e.addBinary('\x00', v.Slice(0, v.Len()).Interface().([]byte))
} else { } else {
n := v.Len() n := v.Len()
e.addInt32(int32(n)) e.addInt32(int32(n))
e.addBytes(0x00) e.addBytes('\x00')
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
el := v.Index(i) el := v.Index(i)
e.addBytes(byte(el.Uint())) e.addBytes(byte(el.Uint()))
} }
} }
} else { } else {
e.addElemName(0x04, name) e.addElemName('\x04', name)
e.addDoc(v) e.addDoc(v)
} }
@ -399,16 +399,11 @@ func (e *encoder) addElem(name string, v reflect.Value, minSize bool) {
e.addBytes(s.Data...) e.addBytes(s.Data...)
case Binary: case Binary:
e.addElemName(0x05, name) e.addElemName('\x05', name)
e.addBinary(s.Kind, s.Data) e.addBinary(s.Kind, s.Data)
case Decimal128:
e.addElemName(0x13, name)
e.addInt64(int64(s.l))
e.addInt64(int64(s.h))
case DBPointer: case DBPointer:
e.addElemName(0x0C, name) e.addElemName('\x0C', name)
e.addStr(s.Namespace) e.addStr(s.Namespace)
if len(s.Id) != 12 { if len(s.Id) != 12 {
panic("ObjectIDs must be exactly 12 bytes long (got " + panic("ObjectIDs must be exactly 12 bytes long (got " +
@ -417,16 +412,16 @@ func (e *encoder) addElem(name string, v reflect.Value, minSize bool) {
e.addBytes([]byte(s.Id)...) e.addBytes([]byte(s.Id)...)
case RegEx: case RegEx:
e.addElemName(0x0B, name) e.addElemName('\x0B', name)
e.addCStr(s.Pattern) e.addCStr(s.Pattern)
e.addCStr(s.Options) e.addCStr(s.Options)
case JavaScript: case JavaScript:
if s.Scope == nil { if s.Scope == nil {
e.addElemName(0x0D, name) e.addElemName('\x0D', name)
e.addStr(s.Code) e.addStr(s.Code)
} else { } else {
e.addElemName(0x0F, name) e.addElemName('\x0F', name)
start := e.reserveInt32() start := e.reserveInt32()
e.addStr(s.Code) e.addStr(s.Code)
e.addDoc(reflect.ValueOf(s.Scope)) e.addDoc(reflect.ValueOf(s.Scope))
@ -435,18 +430,18 @@ func (e *encoder) addElem(name string, v reflect.Value, minSize bool) {
case time.Time: case time.Time:
// MongoDB handles timestamps as milliseconds. // MongoDB handles timestamps as milliseconds.
e.addElemName(0x09, name) e.addElemName('\x09', name)
e.addInt64(s.Unix()*1000 + int64(s.Nanosecond()/1e6)) e.addInt64(s.Unix()*1000 + int64(s.Nanosecond()/1e6))
case url.URL: case url.URL:
e.addElemName(0x02, name) e.addElemName('\x02', name)
e.addStr(s.String()) e.addStr(s.String())
case undefined: case undefined:
e.addElemName(0x06, name) e.addElemName('\x06', name)
default: default:
e.addElemName(0x03, name) e.addElemName('\x03', name)
e.addDoc(v) e.addDoc(v)
} }

380
vendor/gopkg.in/mgo.v2/bson/json.go generated vendored
View file

@ -1,380 +0,0 @@
package bson
import (
"bytes"
"encoding/base64"
"fmt"
"gopkg.in/mgo.v2/internal/json"
"strconv"
"time"
)
// UnmarshalJSON unmarshals a JSON value that may hold non-standard
// syntax as defined in BSON's extended JSON specification.
func UnmarshalJSON(data []byte, value interface{}) error {
d := json.NewDecoder(bytes.NewBuffer(data))
d.Extend(&jsonExt)
return d.Decode(value)
}
// MarshalJSON marshals a JSON value that may hold non-standard
// syntax as defined in BSON's extended JSON specification.
func MarshalJSON(value interface{}) ([]byte, error) {
var buf bytes.Buffer
e := json.NewEncoder(&buf)
e.Extend(&jsonExt)
err := e.Encode(value)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// jdec is used internally by the JSON decoding functions
// so they may unmarshal functions without getting into endless
// recursion due to keyed objects.
func jdec(data []byte, value interface{}) error {
d := json.NewDecoder(bytes.NewBuffer(data))
d.Extend(&funcExt)
return d.Decode(value)
}
var jsonExt json.Extension
var funcExt json.Extension
// TODO
// - Shell regular expressions ("/regexp/opts")
func init() {
jsonExt.DecodeUnquotedKeys(true)
jsonExt.DecodeTrailingCommas(true)
funcExt.DecodeFunc("BinData", "$binaryFunc", "$type", "$binary")
jsonExt.DecodeKeyed("$binary", jdecBinary)
jsonExt.DecodeKeyed("$binaryFunc", jdecBinary)
jsonExt.EncodeType([]byte(nil), jencBinarySlice)
jsonExt.EncodeType(Binary{}, jencBinaryType)
funcExt.DecodeFunc("ISODate", "$dateFunc", "S")
funcExt.DecodeFunc("new Date", "$dateFunc", "S")
jsonExt.DecodeKeyed("$date", jdecDate)
jsonExt.DecodeKeyed("$dateFunc", jdecDate)
jsonExt.EncodeType(time.Time{}, jencDate)
funcExt.DecodeFunc("Timestamp", "$timestamp", "t", "i")
jsonExt.DecodeKeyed("$timestamp", jdecTimestamp)
jsonExt.EncodeType(MongoTimestamp(0), jencTimestamp)
funcExt.DecodeConst("undefined", Undefined)
jsonExt.DecodeKeyed("$regex", jdecRegEx)
jsonExt.EncodeType(RegEx{}, jencRegEx)
funcExt.DecodeFunc("ObjectId", "$oidFunc", "Id")
jsonExt.DecodeKeyed("$oid", jdecObjectId)
jsonExt.DecodeKeyed("$oidFunc", jdecObjectId)
jsonExt.EncodeType(ObjectId(""), jencObjectId)
funcExt.DecodeFunc("DBRef", "$dbrefFunc", "$ref", "$id")
jsonExt.DecodeKeyed("$dbrefFunc", jdecDBRef)
funcExt.DecodeFunc("NumberLong", "$numberLongFunc", "N")
jsonExt.DecodeKeyed("$numberLong", jdecNumberLong)
jsonExt.DecodeKeyed("$numberLongFunc", jdecNumberLong)
jsonExt.EncodeType(int64(0), jencNumberLong)
jsonExt.EncodeType(int(0), jencInt)
funcExt.DecodeConst("MinKey", MinKey)
funcExt.DecodeConst("MaxKey", MaxKey)
jsonExt.DecodeKeyed("$minKey", jdecMinKey)
jsonExt.DecodeKeyed("$maxKey", jdecMaxKey)
jsonExt.EncodeType(orderKey(0), jencMinMaxKey)
jsonExt.DecodeKeyed("$undefined", jdecUndefined)
jsonExt.EncodeType(Undefined, jencUndefined)
jsonExt.Extend(&funcExt)
}
func fbytes(format string, args ...interface{}) []byte {
var buf bytes.Buffer
fmt.Fprintf(&buf, format, args...)
return buf.Bytes()
}
func jdecBinary(data []byte) (interface{}, error) {
var v struct {
Binary []byte `json:"$binary"`
Type string `json:"$type"`
Func struct {
Binary []byte `json:"$binary"`
Type int64 `json:"$type"`
} `json:"$binaryFunc"`
}
err := jdec(data, &v)
if err != nil {
return nil, err
}
var binData []byte
var binKind int64
if v.Type == "" && v.Binary == nil {
binData = v.Func.Binary
binKind = v.Func.Type
} else if v.Type == "" {
return v.Binary, nil
} else {
binData = v.Binary
binKind, err = strconv.ParseInt(v.Type, 0, 64)
if err != nil {
binKind = -1
}
}
if binKind == 0 {
return binData, nil
}
if binKind < 0 || binKind > 255 {
return nil, fmt.Errorf("invalid type in binary object: %s", data)
}
return Binary{Kind: byte(binKind), Data: binData}, nil
}
func jencBinarySlice(v interface{}) ([]byte, error) {
in := v.([]byte)
out := make([]byte, base64.StdEncoding.EncodedLen(len(in)))
base64.StdEncoding.Encode(out, in)
return fbytes(`{"$binary":"%s","$type":"0x0"}`, out), nil
}
func jencBinaryType(v interface{}) ([]byte, error) {
in := v.(Binary)
out := make([]byte, base64.StdEncoding.EncodedLen(len(in.Data)))
base64.StdEncoding.Encode(out, in.Data)
return fbytes(`{"$binary":"%s","$type":"0x%x"}`, out, in.Kind), nil
}
const jdateFormat = "2006-01-02T15:04:05.999Z"
func jdecDate(data []byte) (interface{}, error) {
var v struct {
S string `json:"$date"`
Func struct {
S string
} `json:"$dateFunc"`
}
_ = jdec(data, &v)
if v.S == "" {
v.S = v.Func.S
}
if v.S != "" {
for _, format := range []string{jdateFormat, "2006-01-02"} {
t, err := time.Parse(format, v.S)
if err == nil {
return t, nil
}
}
return nil, fmt.Errorf("cannot parse date: %q", v.S)
}
var vn struct {
Date struct {
N int64 `json:"$numberLong,string"`
} `json:"$date"`
Func struct {
S int64
} `json:"$dateFunc"`
}
err := jdec(data, &vn)
if err != nil {
return nil, fmt.Errorf("cannot parse date: %q", data)
}
n := vn.Date.N
if n == 0 {
n = vn.Func.S
}
return time.Unix(n/1000, n%1000*1e6).UTC(), nil
}
func jencDate(v interface{}) ([]byte, error) {
t := v.(time.Time)
return fbytes(`{"$date":%q}`, t.Format(jdateFormat)), nil
}
func jdecTimestamp(data []byte) (interface{}, error) {
var v struct {
Func struct {
T int32 `json:"t"`
I int32 `json:"i"`
} `json:"$timestamp"`
}
err := jdec(data, &v)
if err != nil {
return nil, err
}
return MongoTimestamp(uint64(v.Func.T)<<32 | uint64(uint32(v.Func.I))), nil
}
func jencTimestamp(v interface{}) ([]byte, error) {
ts := uint64(v.(MongoTimestamp))
return fbytes(`{"$timestamp":{"t":%d,"i":%d}}`, ts>>32, uint32(ts)), nil
}
func jdecRegEx(data []byte) (interface{}, error) {
var v struct {
Regex string `json:"$regex"`
Options string `json:"$options"`
}
err := jdec(data, &v)
if err != nil {
return nil, err
}
return RegEx{v.Regex, v.Options}, nil
}
func jencRegEx(v interface{}) ([]byte, error) {
re := v.(RegEx)
type regex struct {
Regex string `json:"$regex"`
Options string `json:"$options"`
}
return json.Marshal(regex{re.Pattern, re.Options})
}
func jdecObjectId(data []byte) (interface{}, error) {
var v struct {
Id string `json:"$oid"`
Func struct {
Id string
} `json:"$oidFunc"`
}
err := jdec(data, &v)
if err != nil {
return nil, err
}
if v.Id == "" {
v.Id = v.Func.Id
}
return ObjectIdHex(v.Id), nil
}
func jencObjectId(v interface{}) ([]byte, error) {
return fbytes(`{"$oid":"%s"}`, v.(ObjectId).Hex()), nil
}
func jdecDBRef(data []byte) (interface{}, error) {
// TODO Support unmarshaling $ref and $id into the input value.
var v struct {
Obj map[string]interface{} `json:"$dbrefFunc"`
}
// TODO Fix this. Must not be required.
v.Obj = make(map[string]interface{})
err := jdec(data, &v)
if err != nil {
return nil, err
}
return v.Obj, nil
}
func jdecNumberLong(data []byte) (interface{}, error) {
var v struct {
N int64 `json:"$numberLong,string"`
Func struct {
N int64 `json:",string"`
} `json:"$numberLongFunc"`
}
var vn struct {
N int64 `json:"$numberLong"`
Func struct {
N int64
} `json:"$numberLongFunc"`
}
err := jdec(data, &v)
if err != nil {
err = jdec(data, &vn)
v.N = vn.N
v.Func.N = vn.Func.N
}
if err != nil {
return nil, err
}
if v.N != 0 {
return v.N, nil
}
return v.Func.N, nil
}
func jencNumberLong(v interface{}) ([]byte, error) {
n := v.(int64)
f := `{"$numberLong":"%d"}`
if n <= 1<<53 {
f = `{"$numberLong":%d}`
}
return fbytes(f, n), nil
}
func jencInt(v interface{}) ([]byte, error) {
n := v.(int)
f := `{"$numberLong":"%d"}`
if n <= 1<<53 {
f = `%d`
}
return fbytes(f, n), nil
}
func jdecMinKey(data []byte) (interface{}, error) {
var v struct {
N int64 `json:"$minKey"`
}
err := jdec(data, &v)
if err != nil {
return nil, err
}
if v.N != 1 {
return nil, fmt.Errorf("invalid $minKey object: %s", data)
}
return MinKey, nil
}
func jdecMaxKey(data []byte) (interface{}, error) {
var v struct {
N int64 `json:"$maxKey"`
}
err := jdec(data, &v)
if err != nil {
return nil, err
}
if v.N != 1 {
return nil, fmt.Errorf("invalid $maxKey object: %s", data)
}
return MaxKey, nil
}
func jencMinMaxKey(v interface{}) ([]byte, error) {
switch v.(orderKey) {
case MinKey:
return []byte(`{"$minKey":1}`), nil
case MaxKey:
return []byte(`{"$maxKey":1}`), nil
}
panic(fmt.Sprintf("invalid $minKey/$maxKey value: %d", v))
}
func jdecUndefined(data []byte) (interface{}, error) {
var v struct {
B bool `json:"$undefined"`
}
err := jdec(data, &v)
if err != nil {
return nil, err
}
if !v.B {
return nil, fmt.Errorf("invalid $undefined object: %s", data)
}
return Undefined, nil
}
func jencUndefined(v interface{}) ([]byte, error) {
return []byte(`{"$undefined":true}`), nil
}

6
vendor/vendor.json vendored
View file

@ -195,10 +195,10 @@
"revisionTime": "2016-08-01T21:38:24Z" "revisionTime": "2016-08-01T21:38:24Z"
}, },
{ {
"checksumSHA1": "X+UmZuc1xY9x8Bj/qVnQNQnGFV0=", "checksumSHA1": "zTjQOFGy4XTv4L33Kd2FhrV+mbM=",
"path": "gopkg.in/mgo.v2/bson", "path": "gopkg.in/mgo.v2/bson",
"revision": "01084657862d7b12d3b10ffd0394357abf8f8bc2", "revision": "29cc868a5ca65f401ff318143f9408d02f4799cc",
"revisionTime": "2016-08-01T21:38:24Z" "revisionTime": "2016-06-09T18:00:28Z"
}, },
{ {
"checksumSHA1": "XQsrqoNT1U0KzLxOFcAZVvqhLfk=", "checksumSHA1": "XQsrqoNT1U0KzLxOFcAZVvqhLfk=",