Skip to content

Commit

Permalink
Render byte-slices and byte-arrays using hexdump.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmalloc committed Nov 5, 2019
1 parent 563ce41 commit 8c524a0
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 1 deletion.
22 changes: 21 additions & 1 deletion array.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package dapper

import (
"encoding/hex"
"io"
"reflect"

"github.com/dogmatiq/iago/indent"
"github.com/dogmatiq/iago/must"
)

// byteType is the reflect.Type of the built-in byte type.
var byteType = reflect.TypeOf((*byte)(nil)).Elem()

// visitArray formats values with a kind of reflect.Array or Slice.
func (vis *visitor) visitArray(w io.Writer, v Value) {
if v.IsAmbiguousType() {
Expand All @@ -19,8 +23,14 @@ func (vis *visitor) visitArray(w io.Writer, v Value) {
return
}

i := indent.NewIndenter(w, vis.indent)

must.WriteString(w, "{\n")
vis.visitArrayValues(indent.NewIndenter(w, vis.indent), v)
if v.DynamicType.Elem() == byteType {
vis.visitByteArrayValues(i, v)
} else {
vis.visitArrayValues(i, v)
}
must.WriteByte(w, '}')
}

Expand Down Expand Up @@ -52,3 +62,13 @@ func (vis *visitor) visitArrayValues(w io.Writer, v Value) {
must.WriteString(w, "\n")
}
}

func (vis *visitor) visitByteArrayValues(w io.Writer, v Value) {
d := hex.Dumper(w)
defer d.Close()

for i := 0; i < v.Value.Len(); i++ {
octet := byte(v.Value.Index(i).Uint())
must.WriteByte(d, octet)
}
}
21 changes: 21 additions & 0 deletions array_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,27 @@ func TestPrinter_Array(t *testing.T) {
)
}

// This test verifies that byte arrays are rendered using hexdump format.
func TestPrinter_ByteArray(t *testing.T) {
data := []byte("Hello, world!\nThis is some sample text which includes some non-printable characters like '\x00'.")
var array [93]byte
copy(array[:], data)

test(
t,
"byte slice",
array,
"[93]uint8{",
" 00000000 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 0a 54 68 |Hello, world!.Th|",
" 00000010 69 73 20 69 73 20 73 6f 6d 65 20 73 61 6d 70 6c |is is some sampl|",
" 00000020 65 20 74 65 78 74 20 77 68 69 63 68 20 69 6e 63 |e text which inc|",
" 00000030 6c 75 64 65 73 20 73 6f 6d 65 20 6e 6f 6e 2d 70 |ludes some non-p|",
" 00000040 72 69 6e 74 61 62 6c 65 20 63 68 61 72 61 63 74 |rintable charact|",
" 00000050 65 72 73 20 6c 69 6b 65 20 27 00 27 2e |ers like '.'.|",
"}",
)
}

// This test verifies the formatting of array values when the type
// information omitted because it can be inferred from the context in which the
// values are rendered.
Expand Down
17 changes: 17 additions & 0 deletions slice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,23 @@ func TestPrinter_Slice(t *testing.T) {
)
}

// This test verifies that byte slices are rendered using hexdump format.
func TestPrinter_ByteSlice(t *testing.T) {
test(
t,
"byte slice",
[]byte("Hello, world!\nThis is some sample text which includes some non-printable characters like '\x00'."),
"[]uint8{",
" 00000000 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 0a 54 68 |Hello, world!.Th|",
" 00000010 69 73 20 69 73 20 73 6f 6d 65 20 73 61 6d 70 6c |is is some sampl|",
" 00000020 65 20 74 65 78 74 20 77 68 69 63 68 20 69 6e 63 |e text which inc|",
" 00000030 6c 75 64 65 73 20 73 6f 6d 65 20 6e 6f 6e 2d 70 |ludes some non-p|",
" 00000040 72 69 6e 74 61 62 6c 65 20 63 68 61 72 61 63 74 |rintable charact|",
" 00000050 65 72 73 20 6c 69 6b 65 20 27 00 27 2e |ers like '.'.|",
"}",
)
}

// This test verifies the formatting of slice values when the type
// information omitted because it can be inferred from the context in which the
// values are rendered.
Expand Down

0 comments on commit 8c524a0

Please sign in to comment.