package rrdformat import ( "fmt" "io" ) type BinaryError struct { msg string ctxPos int ctxDat []byte ctxEOF bool } func newBinError(msg string, ctxFile []byte, ctxStart, ctxLen int) error { if ctxStart+ctxLen > len(ctxFile) { ctxLen = len(ctxFile) - ctxStart } return BinaryError{ msg: msg, ctxPos: ctxStart, ctxDat: ctxFile[ctxStart : ctxStart+ctxLen], ctxEOF: ctxStart+ctxLen == len(ctxFile), } } func (e BinaryError) Error() string { return "invalid RRD: " + e.msg } var cAsciiEscapes = map[byte]byte{ 0x00: '0', 0x07: 'a', 0x08: 'b', 0x09: 't', 0x0A: 'n', 0x0B: 'v', 0x0C: 'f', 0x0D: 'r', } func (e BinaryError) Format(s fmt.State, verb rune) { switch verb { case 'v': io.WriteString(s, e.Error()) if s.Flag('+') { fmt.Fprintf(s, "\n\tat byte %d:", e.ctxPos) io.WriteString(s, "\n\t\tascii:") for _, byte := range e.ctxDat { if ' ' <= byte && byte <= '~' { fmt.Fprintf(s, " %c", byte) } else if c, ok := cAsciiEscapes[byte]; ok { fmt.Fprintf(s, " \\%c", c) } else { io.WriteString(s, " ??") } } if e.ctxEOF { io.WriteString(s, " ") } io.WriteString(s, "\n\t\thex :") for _, byte := range e.ctxDat { fmt.Fprintf(s, " %02x", byte) } if e.ctxEOF { io.WriteString(s, " ") } io.WriteString(s, "\n") } case 's': io.WriteString(s, e.Error()) case 'q': fmt.Fprintf(s, "%q", e.Error()) } }