github.com/linuxboot/fiano@v1.2.0/pkg/intel/metadata/common/pretty/pretty.go (about) 1 // Copyright 2017-2021 the LinuxBoot Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package pretty 6 7 import ( 8 "fmt" 9 "reflect" 10 "strings" 11 12 "github.com/dustin/go-humanize" 13 ) 14 15 func Header(depth uint, description string, obj interface{}) string { 16 if description == "" { 17 description = fmt.Sprintf("%T", obj) 18 } 19 switch depth { 20 case 0: 21 description = `----` + description + "----\n" 22 case 1: 23 description = `--` + description + `--` 24 default: 25 description += `:` 26 } 27 description = strings.Repeat(" ", int(depth)) + description 28 return description 29 } 30 31 func SubValue(depth uint, fieldName, valueDescription string, value interface{}, opts ...Option) []string { 32 cfg := getConfig(opts) 33 if cfg.OmitKeySignature { 34 switch fieldName { 35 case "PMSE: Signature", "Key And Signature": 36 return nil 37 } 38 } 39 40 if valueDescription == "" { 41 valueDescription = getDescriptionForValue(depth, value, opts...) 42 } 43 return []string{fmt.Sprintf("%s %s", Header(depth, fieldName, nil), valueDescription)} 44 } 45 46 func getDescriptionForValue(depth uint, value interface{}, opts ...Option) string { 47 v := reflect.ValueOf(value) 48 if v.Kind() == reflect.Ptr && v.IsNil() { 49 return "is not set (nil)" 50 } 51 52 switch value := value.(type) { 53 case interface { 54 PrettyString(depth uint, withHeader bool, opts ...Option) string 55 }: 56 description := value.PrettyString(depth, false, opts...) 57 if len(strings.Split(description, "\n")) > 1 { 58 return "\n" + description 59 } else { 60 return strings.TrimSpace(description) 61 } 62 case fmt.GoStringer: 63 return value.GoString() 64 case fmt.Stringer: 65 return value.String() 66 } 67 68 v = reflect.Indirect(v) 69 switch v.Kind() { 70 case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 71 i := v.Uint() 72 var hexFmt string 73 switch v.Type().Size() { 74 case 1: 75 hexFmt = "0x%02X" 76 case 2: 77 hexFmt = "0x%04X" 78 case 4: 79 hexFmt = "0x%08X" 80 case 8: 81 hexFmt = "0x%16X" 82 } 83 switch { 84 case i < 10: 85 return fmt.Sprintf(hexFmt, i) 86 case i < 65536: 87 return fmt.Sprintf(hexFmt+" (%d)", i, i) 88 default: 89 return fmt.Sprintf(hexFmt+" (%d: %s)", i, i, humanize.IBytes(i)) 90 } 91 92 case reflect.Array: 93 return fmt.Sprintf("0x%X", v.Interface()) 94 95 case reflect.Slice: 96 if v.Len() == 0 { 97 return "empty (len: 0)" 98 } 99 return fmt.Sprintf("0x%X (len: %d)", v.Interface(), v.Len()) 100 } 101 102 return fmt.Sprintf("%#+v (%T)", value, value) 103 }