From c330c9991ab45e7d0685d53e699ef26dba065660 Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Date: Thu, 25 Aug 2016 16:34:34 -0400 Subject: Import tools: 5b883d86fdb4df55036d5dba2ca6f9dfa0750b44 from branch v3.3 ref: 1ac1389bda..5b883d86fd for: 3.3.12 SERVER-25814 Initial vendor import: tools --- src/mongo/gotools/common/json/dbpointer.go | 71 ++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/mongo/gotools/common/json/dbpointer.go (limited to 'src/mongo/gotools/common/json/dbpointer.go') diff --git a/src/mongo/gotools/common/json/dbpointer.go b/src/mongo/gotools/common/json/dbpointer.go new file mode 100644 index 00000000000..24582038576 --- /dev/null +++ b/src/mongo/gotools/common/json/dbpointer.go @@ -0,0 +1,71 @@ +package json + +import ( + "fmt" + "gopkg.in/mgo.v2/bson" + "reflect" +) + +// Transition functions for recognizing DBPointer. +// Adapted from encoding/json/scanner.go. + +// stateDB is the state after reading `DB`. +func stateDBP(s *scanner, c int) int { + if c == 'o' { + s.step = generateState("DBPointer", []byte("inter"), stateConstructor) + return scanContinue + } + return s.error(c, "in literal DBPointer (expecting 'o')") +} + +// Decodes a DBRef literal stored in the underlying byte data into v. +func (d *decodeState) storeDBPointer(v reflect.Value) { + op := d.scanWhile(scanSkipSpace) + if op != scanBeginCtor { + d.error(fmt.Errorf("expected beginning of constructor")) + } + + args := d.ctorInterface() + if len(args) != 2 { + d.error(fmt.Errorf("expected 2 arguments to DBPointer constructor, but %v received", len(args))) + } + switch kind := v.Kind(); kind { + case reflect.Interface: + arg0, ok := args[0].(string) + if !ok { + d.error(fmt.Errorf("expected first argument to DBPointer to be of type string")) + } + arg1, ok := args[1].(ObjectId) + if !ok { + d.error(fmt.Errorf("expected second argument to DBPointer to be of type ObjectId, but ended up being %t", args[1])) + } + id := bson.ObjectIdHex(string(arg1)) + v.Set(reflect.ValueOf(DBPointer{arg0, id})) + default: + d.error(fmt.Errorf("cannot store %v value into %v type", dbPointerType, kind)) + } +} + +// Returns a DBRef literal from the underlying byte data. +func (d *decodeState) getDBPointer() interface{} { + op := d.scanWhile(scanSkipSpace) + if op != scanBeginCtor { + d.error(fmt.Errorf("expected beginning of constructor")) + } + + args := d.ctorInterface() + if err := ctorNumArgsMismatch("DBPointer", 2, len(args)); err != nil { + d.error(err) + } + arg0, ok := args[0].(string) + if !ok { + d.error(fmt.Errorf("expected string for first argument of DBPointer constructor")) + } + arg1, ok := args[1].(ObjectId) + if !ok { + d.error(fmt.Errorf("expected ObjectId for second argument of DBPointer constructor")) + } + id := bson.ObjectIdHex(string(arg1)) + + return DBPointer{arg0, id} +} -- cgit v1.2.1