// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file. // Delete the next line to include in the gob package.// +build ignore package gob // This file is not normally included in the gob package. Used only for debugging the package itself.// Except for reading uints, it is an implementation of a reader that is independent of// the one implemented by Decoder.// To enable the Debug function, delete the +build ignore line above and do// go install import ( "bytes" "fmt" "io" "os" "strings" "sync") var dumpBytes = false // If true, print the remaining bytes in the input buffer at each item. // Init installs the debugging facility. If this file is not compiled in the// package, the tests in codec_test.go are no-ops.func init() { debugFunc = Debug} var ( blanks = bytes.Repeat([]byte{' '}, 3*10) empty = []byte(": <empty>\n") tabs = strings.Repeat("\t", 100)) // tab indents itself when printed.type tab int func (t tab) String() string { n := int(t) if n > len(tabs) { n = len(tabs) } return tabs[0:n]} func (t tab) print() { fmt.Fprint(os.Stderr, t)} // A peekReader wraps an io.Reader, allowing one to peek ahead to see// what's coming without stealing the data from the client of the Reader.type peekReader struct { r io.Reader data []byte // read-ahead data} // newPeekReader returns a peekReader that wraps r.func newPeekReader(r io.Reader) *peekReader { return &peekReader{r: r}} // Read is the usual method. It will first take data that has been read ahead.func (p *peekReader) Read(b []byte) (n int, err error) { if len(p.data) == 0 { return p.r.Read(b) } // Satisfy what's possible from the read-ahead data. n = copy(b, p.data) // Move data down to beginning of slice, to avoid endless growth copy(p.data, p.data[n:]) p.data = p.data[:len(p.data)-n] return} // peek returns as many bytes as possible from the unread// portion of the stream, up to the length of b.func (p *peekReader) peek(b []byte) (n int, err error) { if len(p.data) > 0 { n = copy(b, p.data) if n == len(b) { return } b = b[n:] } if len(b) == 0 { return } m, e := io.ReadFull(p.r, b) if m > 0 { p.data = append(p.data, b[:m]...) } n += m if e == io.ErrUnexpectedEOF { // That means m > 0 but we reached EOF. If we got data // we won't complain about not being able to peek enough. if n > 0 { e = nil } else { e = io.EOF } } return n, e} type debugger struct { mutex sync.Mutex remain int // the number of bytes known to remain in the input remainingKnown bool // the value of 'remain' is valid r *peekReader wireType map[typeId]*wireType tmp []byte // scratch space for decoding uints.} // dump prints the next nBytes of the input.// It arranges to print the output aligned from call to// call, to make it easy to see what has been consumed.func (deb *debugger) dump(format string, args ...interface{}) { if !dumpBytes { return } fmt.Fprintf(os.Stderr, format+" ", args...) if !deb.remainingKnown { return } if deb.remain < 0 { fmt.Fprintf(os.Stderr, "remaining byte count is negative! %d\n", deb.remain) return } data := make([]byte, deb.remain) n, _ := deb.r.peek(data) if n == 0 { os.Stderr.Write(empty) return } b := new(bytes.Buffer) fmt.Fprintf(b, "[%d]{\n", deb.remain) // Blanks until first byte lineLength := 0 if n := len(data); n%10 != 0 { lineLength = 10 - n%10 fmt.Fprintf(b, "\t%s", blanks[:lineLength*3]) } // 10 bytes per line for len(data) > 0 { if lineLength == 0 { fmt.Fprint(b, "\t") } m := 10 - lineLength lineLength = 0 if m > len(data) { m = len(data) } fmt.Fprintf(b, "% x\n", data[:m]) data = data[m:] } fmt.Fprint(b, "}\n") os.Stderr.Write(b.Bytes())} // Debug prints a human-readable representation of the gob data read from r.// It is a no-op unless debugging was enabled when the package was built.func Debug(r io.Reader) { err := debug(r) if err != nil { fmt.Fprintf(os.Stderr, "gob debug: %s\n", err) }} // debug implements Debug, but catches panics and returns// them as errors to be printed by Debug.func debug(r io.Reader) (err error) { defer catchError(&err) fmt.Fprintln(os.Stderr, "Start of debugging") deb := &debugger{ r: newPeekReader(r), wireType: make(map[typeId]*wireType), tmp: make([]byte, 16), } if b, ok := r.(*bytes.Buffer); ok { deb.remain = b.Len() deb.remainingKnown = true } deb.gobStream() return} // note that we've consumed some bytesfunc (deb *debugger) consumed(n int) { if deb.remainingKnown { deb.remain -= n }} // int64 decodes and returns the next integer, which must be present.// Don't call this if you could be at EOF.func (deb *debugger) int64() int64 { return toInt(deb.uint64())} // uint64 returns and decodes the next unsigned integer, which must be present.// Don't call this if you could be at EOF.// TODO: handle errors better.func (deb *debugger) uint64() uint64 { n, w, err := decodeUintReader(deb.r, deb.tmp) if err != nil { errorf("debug: read error: %s", err) } deb.consumed(w) return n} // GobStream:// DelimitedMessage* (until EOF)func (deb *debugger) gobStream() { // Make sure we're single-threaded through here. deb.mutex.Lock() defer deb.mutex.Unlock() for deb.delimitedMessage(0) { }} // DelimitedMessage:// uint(lengthOfMessage) Messagefunc (deb *debugger) delimitedMessage(indent tab) bool { for { n := deb.loadBlock(true) if n < 0 { return false } deb.dump("Delimited message of length %d", n) deb.message(indent) } return true} // loadBlock preps us to read a message// of the length specified next in the input. It returns// the length of the block. The argument tells whether// an EOF is acceptable now. If it is and one is found,// the return value is negative.func (deb *debugger) loadBlock(eofOK bool) int { n64, w, err := decodeUintReader(deb.r, deb.tmp) // deb.uint64 will error at EOF if err != nil { if eofOK && err == io.EOF { return -1 } errorf("debug: unexpected error: %s", err) } deb.consumed(w) n := int(n64) if n < 0 { errorf("huge value for message length: %d", n64) } return int(n)} // Message:// TypeSequence TypedValue// TypeSequence// (TypeDefinition DelimitedTypeDefinition*)?// DelimitedTypeDefinition:// uint(lengthOfTypeDefinition) TypeDefinition// TypedValue:// int(typeId) Valuefunc (deb *debugger) message(indent tab) bool { for { // Convert the uint64 to a signed integer typeId uid := deb.int64() id := typeId(uid) deb.dump("type id=%d", id) if id < 0 { deb.typeDefinition(indent, -id) n := deb.loadBlock(false) deb.dump("Message of length %d", n) continue } else { deb.value(indent, id) break } } return true} // Helper methods to make it easy to scan a type descriptor. // common returns the CommonType at the input point.func (deb *debugger) common() CommonType { fieldNum := -1 name := "" id := typeId(0) for { delta := deb.delta(-1) if delta == 0 { break } fieldNum += delta switch fieldNum { case 0: name = deb.string() case 1: // Id typeId id = deb.typeId() default: errorf("corrupted CommonType, delta is %d fieldNum is %d", delta, fieldNum) } } return CommonType{name, id}} // uint returns the unsigned int at the input point, as a uint (not uint64).func (deb *debugger) uint() uint { return uint(deb.uint64())} // int returns the signed int at the input point, as an int (not int64).func (deb *debugger) int() int { return int(deb.int64())} // typeId returns the type id at the input point.func (deb *debugger) typeId() typeId { return typeId(deb.int64())} // string returns the string at the input point.func (deb *debugger) string() string { x := int(deb.uint64()) b := make([]byte, x) nb, _ := deb.r.Read(b) if nb != x { errorf("corrupted type") } deb.consumed(nb) return string(b)} // delta returns the field delta at the input point. The expect argument,// if non-negative, identifies what the value should be.func (deb *debugger) delta(expect int) int { delta := int(deb.uint64()) if delta < 0 || (expect >= 0 && delta != expect) { errorf("decode: corrupted type: delta %d expected %d", delta, expect) } return delta} // TypeDefinition:// [int(-typeId) (already read)] encodingOfWireTypefunc (deb *debugger) typeDefinition(indent tab, id typeId) { deb.dump("type definition for id %d", id) // Encoding is of a wireType. Decode the structure as usual fieldNum := -1 wire := new(wireType) // A wireType defines a single field. delta := deb.delta(-1) fieldNum += delta switch fieldNum { case 0: // array type, one field of {{Common}, elem, length} // Field number 0 is CommonType deb.delta(1) com := deb.common() // Field number 1 is type Id of elem deb.delta(1) id := deb.typeId() // Field number 3 is length deb.delta(1) length := deb.int() wire.ArrayT = &arrayType{com, id, length} case 1: // slice type, one field of {{Common}, elem} // Field number 0 is CommonType deb.delta(1) com := deb.common() // Field number 1 is type Id of elem deb.delta(1) id := deb.typeId() wire.SliceT = &sliceType{com, id} case 2: // struct type, one field of {{Common}, []fieldType} // Field number 0 is CommonType deb.delta(1) com := deb.common() // Field number 1 is slice of FieldType deb.delta(1) numField := int(deb.uint()) field := make([]*fieldType, numField) for i := 0; i < numField; i++ { field[i] = new(fieldType) deb.delta(1) // field 0 of fieldType: name field[i].Name = deb.string() deb.delta(1) // field 1 of fieldType: id field[i].Id = deb.typeId() deb.delta(0) // end of fieldType } wire.StructT = &structType{com, field} case 3: // map type, one field of {{Common}, key, elem} // Field number 0 is CommonType deb.delta(1) com := deb.common() // Field number 1 is type Id of key deb.delta(1) keyId := deb.typeId() // Field number 2 is type Id of elem deb.delta(1) elemId := deb.typeId() wire.MapT = &mapType{com, keyId, elemId} case 4: // GobEncoder type, one field of {{Common}} // Field number 0 is CommonType deb.delta(1) com := deb.common() wire.GobEncoderT = &gobEncoderType{com} case 5: // BinaryMarshaler type, one field of {{Common}} // Field number 0 is CommonType deb.delta(1) com := deb.common() wire.BinaryMarshalerT = &gobEncoderType{com} case 6: // TextMarshaler type, one field of {{Common}} // Field number 0 is CommonType deb.delta(1) com := deb.common() wire.TextMarshalerT = &gobEncoderType{com} default: errorf("bad field in type %d", fieldNum) } deb.printWireType(indent, wire) deb.delta(0) // end inner type (arrayType, etc.) deb.delta(0) // end wireType // Remember we've seen this type. deb.wireType[id] = wire} // Value:// SingletonValue | StructValuefunc (deb *debugger) value(indent tab, id typeId) { wire, ok := deb.wireType[id] if ok && wire.StructT != nil { deb.structValue(indent, id) } else { deb.singletonValue(indent, id) }} // SingletonValue:// uint(0) FieldValuefunc (deb *debugger) singletonValue(indent tab, id typeId) { deb.dump("Singleton value") // is it a builtin type? wire := deb.wireType[id] _, ok := builtinIdToType[id] if !ok && wire == nil { errorf("type id %d not defined", id) } m := deb.uint64() if m != 0 { errorf("expected zero; got %d", m) } deb.fieldValue(indent, id)} // InterfaceValue:// NilInterfaceValue | NonNilInterfaceValuefunc (deb *debugger) interfaceValue(indent tab) { deb.dump("Start of interface value") if nameLen := deb.uint64(); nameLen == 0 { deb.nilInterfaceValue(indent) } else { deb.nonNilInterfaceValue(indent, int(nameLen)) }} // NilInterfaceValue:// uint(0) [already read]func (deb *debugger) nilInterfaceValue(indent tab) int { fmt.Fprintf(os.Stderr, "%snil interface\n", indent) return 0} // NonNilInterfaceValue:// ConcreteTypeName TypeSequence InterfaceContents// ConcreteTypeName:// uint(lengthOfName) [already read=n] name// InterfaceContents:// int(concreteTypeId) DelimitedValue// DelimitedValue:// uint(length) Valuefunc (deb *debugger) nonNilInterfaceValue(indent tab, nameLen int) { // ConcreteTypeName b := make([]byte, nameLen) deb.r.Read(b) // TODO: CHECK THESE READS!! deb.consumed(nameLen) name := string(b) for { id := deb.typeId()Lines 1–500 of 705. Load more
// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Delete the next line to include in the gob package. // +build ignore package gob // This file is not normally included in the gob package. Used only for debugging the package itself. // Except for reading uints, it is an implementation of a reader that is independent of // the one implemented by Decoder. // To enable the Debug function, delete the +build ignore line above and do // go install import ( "bytes" "fmt" "io" "os" "strings" "sync" ) var dumpBytes = false // If true, print the remaining bytes in the input buffer at each item. // Init installs the debugging facility. If this file is not compiled in the // package, the tests in codec_test.go are no-ops. func init() { debugFunc = Debug } var ( blanks = bytes.Repeat([]byte{' '}, 3*10) empty = []byte(": <empty>\n") tabs = strings.Repeat("\t", 100) ) // tab indents itself when printed. type tab int func (t tab) String() string { n := int(t) if n > len(tabs) { n = len(tabs) } return tabs[0:n] } func (t tab) print() { fmt.Fprint(os.Stderr, t) } // A peekReader wraps an io.Reader, allowing one to peek ahead to see // what's coming without stealing the data from the client of the Reader. type peekReader struct { r io.Reader data []byte // read-ahead data } // newPeekReader returns a peekReader that wraps r. func newPeekReader(r io.Reader) *peekReader { return &peekReader{r: r} } // Read is the usual method. It will first take data that has been read ahead. func (p *peekReader) Read(b []byte) (n int, err error) { if len(p.data) == 0 { return p.r.Read(b) } // Satisfy what's possible from the read-ahead data. n = copy(b, p.data) // Move data down to beginning of slice, to avoid endless growth copy(p.data, p.data[n:]) p.data = p.data[:len(p.data)-n] return } // peek returns as many bytes as possible from the unread // portion of the stream, up to the length of b. func (p *peekReader) peek(b []byte) (n int, err error) { if len(p.data) > 0 { n = copy(b, p.data) if n == len(b) { return } b = b[n:] } if len(b) == 0 { return } m, e := io.ReadFull(p.r, b) if m > 0 { p.data = append(p.data, b[:m]...) } n += m if e == io.ErrUnexpectedEOF { // That means m > 0 but we reached EOF. If we got data // we won't complain about not being able to peek enough. if n > 0 { e = nil } else { e = io.EOF } } return n, e } type debugger struct { mutex sync.Mutex remain int // the number of bytes known to remain in the input remainingKnown bool // the value of 'remain' is valid r *peekReader wireType map[typeId]*wireType tmp []byte // scratch space for decoding uints. } // dump prints the next nBytes of the input. // It arranges to print the output aligned from call to // call, to make it easy to see what has been consumed. func (deb *debugger) dump(format string, args ...interface{}) { if !dumpBytes { return } fmt.Fprintf(os.Stderr, format+" ", args...) if !deb.remainingKnown { return } if deb.remain < 0 { fmt.Fprintf(os.Stderr, "remaining byte count is negative! %d\n", deb.remain) return } data := make([]byte, deb.remain) n, _ := deb.r.peek(data) if n == 0 { os.Stderr.Write(empty) return } b := new(bytes.Buffer) fmt.Fprintf(b, "[%d]{\n", deb.remain) // Blanks until first byte lineLength := 0 if n := len(data); n%10 != 0 { lineLength = 10 - n%10 fmt.Fprintf(b, "\t%s", blanks[:lineLength*3]) } // 10 bytes per line for len(data) > 0 { if lineLength == 0 { fmt.Fprint(b, "\t") } m := 10 - lineLength lineLength = 0 if m > len(data) { m = len(data) } fmt.Fprintf(b, "% x\n", data[:m]) data = data[m:] } fmt.Fprint(b, "}\n") os.Stderr.Write(b.Bytes()) } // Debug prints a human-readable representation of the gob data read from r. // It is a no-op unless debugging was enabled when the package was built. func Debug(r io.Reader) { err := debug(r) if err != nil { fmt.Fprintf(os.Stderr, "gob debug: %s\n", err) } } // debug implements Debug, but catches panics and returns // them as errors to be printed by Debug. func debug(r io.Reader) (err error) { defer catchError(&err) fmt.Fprintln(os.Stderr, "Start of debugging") deb := &debugger{ r: newPeekReader(r), wireType: make(map[typeId]*wireType), tmp: make([]byte, 16), } if b, ok := r.(*bytes.Buffer); ok { deb.remain = b.Len() deb.remainingKnown = true } deb.gobStream() return } // note that we've consumed some bytes func (deb *debugger) consumed(n int) { if deb.remainingKnown { deb.remain -= n } } // int64 decodes and returns the next integer, which must be present. // Don't call this if you could be at EOF. func (deb *debugger) int64() int64 { return toInt(deb.uint64()) } // uint64 returns and decodes the next unsigned integer, which must be present. // Don't call this if you could be at EOF. // TODO: handle errors better. func (deb *debugger) uint64() uint64 { n, w, err := decodeUintReader(deb.r, deb.tmp) if err != nil { errorf("debug: read error: %s", err) } deb.consumed(w) return n } // GobStream: // DelimitedMessage* (until EOF) func (deb *debugger) gobStream() { // Make sure we're single-threaded through here. deb.mutex.Lock() defer deb.mutex.Unlock() for deb.delimitedMessage(0) { } } // DelimitedMessage: // uint(lengthOfMessage) Message func (deb *debugger) delimitedMessage(indent tab) bool { for { n := deb.loadBlock(true) if n < 0 { return false } deb.dump("Delimited message of length %d", n) deb.message(indent) } return true } // loadBlock preps us to read a message // of the length specified next in the input. It returns // the length of the block. The argument tells whether // an EOF is acceptable now. If it is and one is found, // the return value is negative. func (deb *debugger) loadBlock(eofOK bool) int { n64, w, err := decodeUintReader(deb.r, deb.tmp) // deb.uint64 will error at EOF if err != nil { if eofOK && err == io.EOF { return -1 } errorf("debug: unexpected error: %s", err) } deb.consumed(w) n := int(n64) if n < 0 { errorf("huge value for message length: %d", n64) } return int(n) } // Message: // TypeSequence TypedValue // TypeSequence // (TypeDefinition DelimitedTypeDefinition*)? // DelimitedTypeDefinition: // uint(lengthOfTypeDefinition) TypeDefinition // TypedValue: // int(typeId) Value func (deb *debugger) message(indent tab) bool { for { // Convert the uint64 to a signed integer typeId uid := deb.int64() id := typeId(uid) deb.dump("type id=%d", id) if id < 0 { deb.typeDefinition(indent, -id) n := deb.loadBlock(false) deb.dump("Message of length %d", n) continue } else { deb.value(indent, id) break } } return true } // Helper methods to make it easy to scan a type descriptor. // common returns the CommonType at the input point. func (deb *debugger) common() CommonType { fieldNum := -1 name := "" id := typeId(0) for { delta := deb.delta(-1) if delta == 0 { break } fieldNum += delta switch fieldNum { case 0: name = deb.string() case 1: // Id typeId id = deb.typeId() default: errorf("corrupted CommonType, delta is %d fieldNum is %d", delta, fieldNum) } } return CommonType{name, id} } // uint returns the unsigned int at the input point, as a uint (not uint64). func (deb *debugger) uint() uint { return uint(deb.uint64()) } // int returns the signed int at the input point, as an int (not int64). func (deb *debugger) int() int { return int(deb.int64()) } // typeId returns the type id at the input point. func (deb *debugger) typeId() typeId { return typeId(deb.int64()) } // string returns the string at the input point. func (deb *debugger) string() string { x := int(deb.uint64()) b := make([]byte, x) nb, _ := deb.r.Read(b) if nb != x { errorf("corrupted type") } deb.consumed(nb) return string(b) } // delta returns the field delta at the input point. The expect argument, // if non-negative, identifies what the value should be. func (deb *debugger) delta(expect int) int { delta := int(deb.uint64()) if delta < 0 || (expect >= 0 && delta != expect) { errorf("decode: corrupted type: delta %d expected %d", delta, expect) } return delta } // TypeDefinition: // [int(-typeId) (already read)] encodingOfWireType func (deb *debugger) typeDefinition(indent tab, id typeId) { deb.dump("type definition for id %d", id) // Encoding is of a wireType. Decode the structure as usual fieldNum := -1 wire := new(wireType) // A wireType defines a single field. delta := deb.delta(-1) fieldNum += delta switch fieldNum { case 0: // array type, one field of {{Common}, elem, length} // Field number 0 is CommonType deb.delta(1) com := deb.common() // Field number 1 is type Id of elem deb.delta(1) id := deb.typeId() // Field number 3 is length deb.delta(1) length := deb.int() wire.ArrayT = &arrayType{com, id, length} case 1: // slice type, one field of {{Common}, elem} // Field number 0 is CommonType deb.delta(1) com := deb.common() // Field number 1 is type Id of elem deb.delta(1) id := deb.typeId() wire.SliceT = &sliceType{com, id} case 2: // struct type, one field of {{Common}, []fieldType} // Field number 0 is CommonType deb.delta(1) com := deb.common() // Field number 1 is slice of FieldType deb.delta(1) numField := int(deb.uint()) field := make([]*fieldType, numField) for i := 0; i < numField; i++ { field[i] = new(fieldType) deb.delta(1) // field 0 of fieldType: name field[i].Name = deb.string() deb.delta(1) // field 1 of fieldType: id field[i].Id = deb.typeId() deb.delta(0) // end of fieldType } wire.StructT = &structType{com, field} case 3: // map type, one field of {{Common}, key, elem} // Field number 0 is CommonType deb.delta(1) com := deb.common() // Field number 1 is type Id of key deb.delta(1) keyId := deb.typeId() // Field number 2 is type Id of elem deb.delta(1) elemId := deb.typeId() wire.MapT = &mapType{com, keyId, elemId} case 4: // GobEncoder type, one field of {{Common}} // Field number 0 is CommonType deb.delta(1) com := deb.common() wire.GobEncoderT = &gobEncoderType{com} case 5: // BinaryMarshaler type, one field of {{Common}} // Field number 0 is CommonType deb.delta(1) com := deb.common() wire.BinaryMarshalerT = &gobEncoderType{com} case 6: // TextMarshaler type, one field of {{Common}} // Field number 0 is CommonType deb.delta(1) com := deb.common() wire.TextMarshalerT = &gobEncoderType{com} default: errorf("bad field in type %d", fieldNum) } deb.printWireType(indent, wire) deb.delta(0) // end inner type (arrayType, etc.) deb.delta(0) // end wireType // Remember we've seen this type. deb.wireType[id] = wire } // Value: // SingletonValue | StructValue func (deb *debugger) value(indent tab, id typeId) { wire, ok := deb.wireType[id] if ok && wire.StructT != nil { deb.structValue(indent, id) } else { deb.singletonValue(indent, id) } } // SingletonValue: // uint(0) FieldValue func (deb *debugger) singletonValue(indent tab, id typeId) { deb.dump("Singleton value") // is it a builtin type? wire := deb.wireType[id] _, ok := builtinIdToType[id] if !ok && wire == nil { errorf("type id %d not defined", id) } m := deb.uint64() if m != 0 { errorf("expected zero; got %d", m) } deb.fieldValue(indent, id) } // InterfaceValue: // NilInterfaceValue | NonNilInterfaceValue func (deb *debugger) interfaceValue(indent tab) { deb.dump("Start of interface value") if nameLen := deb.uint64(); nameLen == 0 { deb.nilInterfaceValue(indent) } else { deb.nonNilInterfaceValue(indent, int(nameLen)) } } // NilInterfaceValue: // uint(0) [already read] func (deb *debugger) nilInterfaceValue(indent tab) int { fmt.Fprintf(os.Stderr, "%snil interface\n", indent) return 0 } // NonNilInterfaceValue: // ConcreteTypeName TypeSequence InterfaceContents // ConcreteTypeName: // uint(lengthOfName) [already read=n] name // InterfaceContents: // int(concreteTypeId) DelimitedValue // DelimitedValue: // uint(length) Value func (deb *debugger) nonNilInterfaceValue(indent tab, nameLen int) { // ConcreteTypeName b := make([]byte, nameLen) deb.r.Read(b) // TODO: CHECK THESE READS!! deb.consumed(nameLen) name := string(b) for { id := deb.typeId()