dotnet / dotnet/fsharp

Improve F# Interactive formatting of byte arrays

Open
#17,071 9 comments 10 reactions 0 assignees View on GitHub
Area-FSI Feature Request
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 22h
Merged PRs (30d)
144

Description

Working with byte arrays in F# is hard, because you don't see the proper content as bytes, neither the text-string-presentation of it. Working with byte-arrays is common scenario that can relate to networks, files, etc.

Example byte array:

```fsharp
let myBytes = "this is a test, this is a test, this is a test.."B
```

The current (non-standard string-presentation):

```
val myBytes: byte array =
[|116uy; 104uy; 105uy; 115uy; 32uy; 105uy; 115uy; 32uy; 97uy; 32uy; 116uy;
101uy; 115uy; 116uy; 44uy; 32uy; 116uy; 104uy; 105uy; 115uy; 32uy; 105uy;
115uy; 32uy; 97uy; 32uy; 116uy; 101uy; 115uy; 116uy; 44uy; 32uy; 116uy;
104uy; 105uy; 115uy; 32uy; 105uy; 115uy; 32uy; 97uy; 32uy; 116uy; 101uy;
115uy; 116uy; 46uy; 46uy|]
```

The standard way (used by Git, hex-editors, etc) would be rendering the array in more visual way:
(hex-line number, tab, 8 hex-bytes + space + 8 hex-bytes, tab, string representation):

```
0000 74 68 69 73 20 69 73 20 61 20 74 65 73 74 2c 20 this is a test,
0010 74 68 69 73 20 69 73 20 61 20 74 65 73 74 2c 20 this is a test,
0020 74 68 69 73 20 69 73 20 61 20 74 65 73 74 2e 2e this is a test..
```

The good news is that this can be done with fairly simple F#-function (open source, original thanks to Christian Steinert):

```fsharp
let getBytesTable (bytes : byte array) =
let maxLen = if bytes.LongLength > 1048576L then 1048576 else bytes.Length
let sb = System.Text.StringBuilder ()
bytes
|> Array.take maxLen
|> Array.iteri (fun i c ->
if i % 16 = 0 then
if i > 0 then sb.AppendLine () |> ignore
sb.AppendFormat("{0:x4}\t", i) |> ignore

sb.AppendFormat("{0:x2}", c) |> ignore
if i % 16 = 7 then sb.Append ' ' |> ignore
elif i % 16 = 15 then
sb.Append " " |> ignore
for i = i - 15 to i do
if bytes.[i] >= 32uy && bytes.[i] <= 126uy
then bytes.[i] |> char
else '\183'
|> sb.Append
|> ignore
if i + 1 < maxLen then sb.Append ' ' |> ignore
)

sb.ToString ()
```

But this function should be part of F# itself as the byte array default presentation format.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.