amuz.es/src/infra/goutils@v0.1.3/misc/dumper.go (about) 1 package misc 2 3 import "bytes" 4 5 import ( 6 "fmt" 7 "unicode/utf8" 8 "golang.org/x/text/width" 9 ) 10 11 func HexDump(by []byte) string { 12 n := len(by) 13 rowcount := 0 14 stop := (n / 16) * 16 15 k := 0 16 buf := &bytes.Buffer{} 17 18 for i := 0; i <= stop; i += 16 { 19 k++ 20 if i+16 < n { 21 rowcount = 16 22 } else { 23 rowcount = min(k*16, n) % 16 24 } 25 26 fmt.Fprintf(buf, "%08x ", i) 27 for j := 0; j < rowcount; j++ { 28 if j%8 == 0 { 29 fmt.Fprintf(buf, " %02x ", by[i+j]) 30 } else { 31 fmt.Fprintf(buf, "%02x ", by[i+j]) 32 } 33 34 } 35 36 for j := rowcount; j < 16; j++ { 37 if j%8 == 0 { 38 fmt.Fprintf(buf, " ") 39 } else { 40 fmt.Fprintf(buf, " ") 41 } 42 } 43 buf.WriteRune('|') 44 viewString(by[i:(i + rowcount)], buf) 45 buf.WriteRune('|') 46 buf.WriteRune('\n') 47 buf.WriteRune('\r') 48 } 49 return buf.String() 50 } 51 52 func max(a, b int) int { 53 if a > b { 54 return a 55 } 56 return b 57 } 58 func min(a, b int) int { 59 if a < b { 60 return a 61 } 62 return b 63 } 64 func GuessUnicodeWidth(char rune) (realSize int) { 65 prop := width.LookupRune(char) 66 switch prop.Kind() { 67 case width.EastAsianFullwidth: 68 fallthrough 69 case width.EastAsianWide: 70 realSize = 2 71 case width.EastAsianHalfwidth: 72 fallthrough 73 case width.EastAsianNarrow: 74 realSize = 2 75 case width.EastAsianAmbiguous: 76 fallthrough 77 case width.Neutral: 78 fallthrough 79 default: 80 realSize = 1 81 } 82 return 83 } 84 85 func FillUnicodeWidth(byteLength int, char rune) int { 86 fillWidth := GuessUnicodeWidth(char) 87 return max(0, byteLength-fillWidth) 88 } 89 func viewString(b []byte, buf *bytes.Buffer) { 90 for { 91 if r, size := utf8.DecodeRune(b); size == 0 { 92 return 93 } else if r == utf8.RuneError { 94 for i := 0; i < size; i++ { 95 buf.WriteRune('_') 96 } 97 b = b[size:] 98 } else if r < 32 { 99 for i := 0; i < size; i++ { 100 buf.WriteRune('.') 101 } 102 b = b[size:] 103 } else { 104 buf.WriteRune(r) 105 pad := FillUnicodeWidth(size, r) 106 for i := 0; i < pad; i++ { 107 buf.WriteRune('.') 108 } 109 b = b[size:] 110 } 111 } 112 }