dump.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package util
  2. import (
  3. "bytes"
  4. "crypto/rsa"
  5. "fmt"
  6. "io"
  7. "reflect"
  8. "strings"
  9. "time"
  10. )
  11. const (
  12. // MaxFieldLen const
  13. MaxFieldLen = 100
  14. // MaxSliceLen const
  15. MaxSliceLen = 100
  16. tabSpace = " "
  17. )
  18. // Dump value
  19. func Dump(v interface{}) string {
  20. var bb bytes.Buffer
  21. fdump(&bb, 0, 0, "", reflect.ValueOf(v))
  22. return bb.String()
  23. }
  24. // Fdump value
  25. func Fdump(w io.Writer, v interface{}) {
  26. fdump(w, 0, 0, "", reflect.ValueOf(v))
  27. }
  28. func fdump(w io.Writer, rx int, rd int, tab string, value reflect.Value) {
  29. rx++
  30. if rx > 100 {
  31. fmt.Fprint(w, "/* too many recursive */")
  32. }
  33. if rd > 10 {
  34. fmt.Fprint(w, "/* too deep */")
  35. }
  36. if value.Kind() == reflect.Interface && !value.IsNil() {
  37. elm := value.Elem()
  38. if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
  39. value = elm
  40. }
  41. }
  42. if value.Kind() == reflect.Ptr {
  43. value = value.Elem()
  44. }
  45. if value.Kind() == reflect.String {
  46. fmt.Fprintf(w, "\"%s\" /* Type:%s */", value, value.Type().String())
  47. } else if kindIn(value.Kind(), reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64) {
  48. fmt.Fprintf(w, "%+v /* Type:%s */", value, value.Type().String())
  49. } else if kindIn(value.Kind(), reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64) {
  50. fmt.Fprintf(w, "%+v /* Type:%s */", value, value.Type().String())
  51. } else if value.Kind() == reflect.Struct {
  52. if value.CanInterface() {
  53. if t, ok := value.Interface().(time.Time); ok {
  54. fmt.Fprintf(w, "%s /* Type:%s */", t, value.Type())
  55. return
  56. }
  57. }
  58. if value.Type() == reflect.TypeOf(rsa.PublicKey{}) {
  59. fmt.Fprintf(w, "- /* Type:%s */", value.Type())
  60. return
  61. }
  62. if value.Type() == reflect.TypeOf(rsa.PrivateKey{}) {
  63. fmt.Fprintf(w, "- /* Type:%s */", value.Type())
  64. return
  65. }
  66. ntab := tab + tabSpace
  67. fmt.Fprintf(w, "{ /* Type:%v:%s-%s */", value.CanInterface(), value.Kind().String(), value.Type().String())
  68. il := value.NumField()
  69. for i, j := 0, 0; i < il && i < MaxFieldLen; i++ {
  70. tf := value.Type().Field(i)
  71. tag := strings.Split(value.Type().Field(i).Tag.Get("dump"), ",")
  72. if !InStringSlice("ignore", tag...) {
  73. if j > 0 {
  74. fmt.Fprintf(w, ",\n%s\"%s\": ", ntab, tf.Name)
  75. } else {
  76. fmt.Fprintf(w, "\n%s\"%s\": ", ntab, tf.Name)
  77. }
  78. vf := value.Field(i)
  79. fdump(w, rx, rd+1, ntab, vf)
  80. j++
  81. }
  82. }
  83. fmt.Fprintf(w, "\n%s}", tab)
  84. } else if value.Kind() == reflect.Slice {
  85. ntab := tab + tabSpace
  86. if value.Type().String() == "[]uint8" {
  87. il := value.Len()
  88. fmt.Fprintf(w, "[ /* Type:%s Length:%v */\n%s 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n%s0000 ", value.Type().String(), il, ntab, ntab)
  89. for i, j := 0, 0; i < il; i++ {
  90. if j == 16 {
  91. fmt.Fprintf(w, "\n%s%04X ", ntab, i)
  92. j = 1
  93. } else {
  94. j++
  95. }
  96. fmt.Fprintf(w, "%02X ", value.Index(i).Interface())
  97. }
  98. fmt.Fprintf(w, "\n%s]%s", tab, "")
  99. } else {
  100. fmt.Fprintf(w, "[ /* Type:%s Length:%v */\n%s", value.Type().String(), value.Len(), ntab)
  101. il := value.Len()
  102. for i := 0; i < il && i < MaxSliceLen; i++ {
  103. vi := value.Index(i)
  104. if i > 0 {
  105. fmt.Fprintf(w, ",\n%s/* Index:%v */ ", ntab, i)
  106. } else {
  107. fmt.Fprint(w, "/* Index:0 */ ")
  108. }
  109. fdump(w, rx, rd+1, ntab, vi)
  110. }
  111. if il > MaxSliceLen {
  112. fmt.Fprintf(w, "\n%s/* too many items */", ntab)
  113. }
  114. fmt.Fprintf(w, "\n%s]%s", tab, "")
  115. }
  116. } else if value.Kind() == reflect.Map {
  117. ntab := tab + tabSpace
  118. fmt.Fprintf(w, "{ /* Type:%s */\n%s", value.Type().String(), ntab)
  119. keys := value.MapKeys()
  120. for k, kv := range keys {
  121. if k > 0 {
  122. fmt.Fprintf(w, ",\n%s\"%v\": ", ntab, kv)
  123. } else {
  124. fmt.Fprintf(w, "\"%v\": ", kv)
  125. }
  126. fdump(w, rx, rd+1, ntab, value.MapIndex(kv))
  127. }
  128. fmt.Fprintf(w, "\n%s}%s", tab, "")
  129. } else if !value.IsValid() {
  130. fmt.Fprint(w, "/* NOT-VALID */")
  131. } else if value.Type() != nil {
  132. fmt.Fprintf(w, "undefined /* Type:%s Value:[%v] */", value.Type().String(), value)
  133. }
  134. }
  135. func kindIn(value reflect.Kind, list ...reflect.Kind) bool {
  136. for _, v := range list {
  137. if value == v {
  138. return true
  139. }
  140. }
  141. return false
  142. }