package xturbo import ( "encoding/binary" "fmt" ) // XError is an X protocol error, passed by value (no interface on the hot path). type XError struct { Seq Seq Code uint8 // wire error code Ext ExtID // ExtCore for codes < 128 or unknown Rel uint8 // Code - FirstError of Ext Bad uint32 // bad resource/value Minor uint16 Major uint8 Kind uint16 // ring slot kind, 0 when the request was not registered Args [4]uint32 Raw [32]byte } // Error formats the error. It allocates: use it for logging only. func (e *XError) Error() string { ext := "core" if e.Ext != ExtCore && e.Ext < extCount { ext = ExtXName[e.Ext] } return fmt.Sprintf("xturbo: X error code %d (%s rel %d) seq %d major %d minor %d bad 0x%x kind %d", e.Code, ext, e.Rel, e.Seq, e.Major, e.Minor, e.Bad, e.Kind) } // decodeError fills e from a 32-byte error packet (raw[0] == 0). Seq is the // 16-bit wire value; Kind/Args are left for the reply ring. Extension codes // resolve through ext; a nil ext or unknown code leaves Ext=ExtCore, Rel=Code. func decodeError(raw []byte, ext *ExtTable, e *XError) bool { if len(raw) < 32 || raw[0] != 0 { return false } *e = XError{ Seq: Seq(binary.LittleEndian.Uint16(raw[2:])), Code: raw[1], Rel: raw[1], Bad: binary.LittleEndian.Uint32(raw[4:]), Minor: binary.LittleEndian.Uint16(raw[8:]), Major: raw[10], } copy(e.Raw[:], raw[:32]) if ext != nil && e.Code >= 128 { if id, rel, ok := ext.ByError(e.Code); ok { e.Ext, e.Rel = id, rel } } return true }