Results 1 to 3 of 3

Thread: Format Byte Array

Threaded View

  1. #1

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Format Byte Array

    I have found this extension useful when debugging methods that use byte arrays. It was originally written to help debug TCP/IP packets and SerialPort data. This extension formats arrays of bytes, shorts, integers, and longs in binary, and optionally shows hex, decimal, and characters. The format is shown below.

    NOTE: Requires ASCIITable

    Code:
    Module FormatBytes
        'Imports System.Runtime.CompilerServices
        ''' <summary>
        ''' Takes an array and formats it for easier reading.  Shows binary by default.
        ''' </summary>
        ''' <param name="buf">the array</param>
        ''' <param name="showChar">show characters</param>
        ''' <param name="showDec">show decimal</param>
        ''' <param name="showHex">show hex</param>
        ''' <param name="dumpfile">a path string or an open IO.Stream</param>
        ''' <param name="encode">encoding - designed for 7-8 bit character sets</param>
        ''' <returns>formatted string</returns>
        ''' <remarks></remarks>
        <Extension()>
        Public Function PrettyByteBuf(buf() As Byte, _
                                      Optional showChar As Boolean = False, _
                                      Optional showDec As Boolean = False, _
                                      Optional showHex As Boolean = False, _
                                      Optional dumpfile As Object = Nothing, _
                                      Optional encode As System.Text.Encoding = Nothing) As String
            If IsNothing(buf) Then Return ""
            Dim rv As New System.Text.StringBuilder
    
            'rquires http://www.vbforums.com/showthread.php?741563-ASCII-Table
            Dim atab As ASCIITable
            If encode Is Nothing Then
                atab = New ASCIITable
            Else
                atab = New ASCIITable(encode)
            End If
    
            Dim hdrl As String = "<<--------------0---------1---------2---------3----<>---4---------5---------6---------7--->>"
            Dim dash As String = "---------------------------------------------------<>---------------------------------------"
            Dim part As Boolean = False
            Const hdrshow As Integer = 32
            For idx As Integer = 0 To buf.Length - 1 Step 8
                If idx Mod hdrshow = 0 Then
                    rv.AppendLine(hdrl)
                End If
                'newline
                rv.Append(String.Format("{0,-10}>  ", idx))
                For x As Integer = 0 To 7
                    Dim y As Integer = x + idx
                    If y >= buf.Length Then
                        part = True
                        Exit For
                    End If
                    Dim ac As ASCIITable.aChar = atab.theChars(buf(y))
                    rv.Append(String.Format("{0,-10}", ac.bin))
                Next
                If showHex Then
                    rv.AppendLine()
                    rv.Append(String.Format("{0,12}   ", "hex"))
                    For x As Integer = 0 To 7
                        Dim y As Integer = x + idx
                        If y >= buf.Length Then Exit For
                        Dim ac As ASCIITable.aChar = atab.theChars(buf(y))
                        rv.Append(String.Format("{0,-10}", ac.hex))
                    Next
                End If
                If showDec Then
                    rv.AppendLine()
                    rv.Append(String.Format("{0,12}   ", "dec"))
                    For x As Integer = 0 To 7
                        Dim y As Integer = x + idx
                        If y >= buf.Length Then Exit For
                        Dim ac As ASCIITable.aChar = atab.theChars(buf(y))
                        rv.Append(String.Format("{0,-10}", ac.code))
                    Next
                End If
                If showChar Then
                    rv.AppendLine()
                    rv.Append(String.Format("{0,12}   ", "ch"))
                    For x As Integer = 0 To 7
                        Dim y As Integer = x + idx
                        If y >= buf.Length Then Exit For
                        Dim ac As ASCIITable.aChar = atab.theChars(buf(y))
                        rv.Append(String.Format("{0,-10}", ac.ch))
                    Next
                End If
                If part Then rv.AppendLine()
                If (showChar OrElse showDec OrElse showHex) AndAlso ((idx + 8) Mod hdrshow <> 0) Then
                    If Not part Then rv.AppendLine()
                    rv.AppendLine(dash)
                Else
                    If Not part Then rv.AppendLine()
                End If
            Next
            If TypeOf (dumpfile) Is String Then
                Dim p As String = DirectCast(dumpfile, String)
                If p <> "" Then
                    rv.AppendLine()
                    rv.AppendLine()
                    Try
                        Dim txtwr As New IO.FileStream(p, FileMode.Append, FileAccess.Write, FileShare.None)
                        Dim b() As Byte = atab.encodingUsed.GetBytes(rv.ToString)
                        txtwr.Write(b, 0, b.Length)
                        txtwr.Close()
                        txtwr.Dispose()
                    Catch ex As Exception
                        Throw
                    End Try
                End If
            ElseIf TypeOf (dumpfile) Is IO.Stream Then
                Try
                    Dim txtwr As IO.Stream = DirectCast(dumpfile, IO.Stream)
                    Dim b() As Byte = atab.encodingUsed.GetBytes(rv.ToString)
                    txtwr.Write(b, 0, b.Length)
                Catch ex As Exception
                    Throw
                End Try
            End If
            Return rv.ToString
        End Function
    
        ''' <summary>
        ''' Takes an array and formats it for easier reading.  Shows binary by default.
        ''' </summary>
        ''' <param name="buf">the array</param>
        ''' <param name="showChar">show characters</param>
        ''' <param name="showDec">show decimal</param>
        ''' <param name="showHex">show hex</param>
        ''' <param name="dumpfile">a path string or an open IO.Stream</param>
        ''' <param name="encode">encoding - designed for 7-8 bit character sets</param>
        ''' <returns>formatted string</returns>
        ''' <remarks></remarks>
        <Extension()>
        Public Function PrettyByteBuf(buf() As Short, _
                                      Optional showChar As Boolean = False, _
                                      Optional showDec As Boolean = False, _
                                      Optional showHex As Boolean = False, _
                                      Optional dumpfile As Object = Nothing, _
                                      Optional encode As System.Text.Encoding = Nothing) As String
            Dim rv As New List(Of Byte)
            Dim mask As Byte = &HFF
            For Each n As Short In buf
                For x As Integer = (16 - 8) To 0 Step -8
                    rv.Add(CByte((n >> x) And mask))
                Next
            Next
            Return rv.ToArray.PrettyByteBuf(showChar, showDec, showHex, dumpfile, encode)
        End Function
    
        ''' <summary>
        ''' Takes an array and formats it for easier reading.  Shows binary by default.
        ''' </summary>
        ''' <param name="buf">the array</param>
        ''' <param name="showChar">show characters</param>
        ''' <param name="showDec">show decimal</param>
        ''' <param name="showHex">show hex</param>
        ''' <param name="dumpfile">a path string or an open IO.Stream</param>
        ''' <param name="encode">encoding - designed for 7-8 bit character sets</param>
        ''' <returns>formatted string</returns>
        ''' <remarks></remarks>
        <Extension()>
        Public Function PrettyByteBuf(buf() As Integer, _
                                      Optional showChar As Boolean = False, _
                                      Optional showDec As Boolean = False, _
                                      Optional showHex As Boolean = False, _
                                      Optional dumpfile As Object = Nothing, _
                                      Optional encode As System.Text.Encoding = Nothing) As String
            Dim rv As New List(Of Byte)
            Dim mask As Byte = &HFF
            For Each n As Integer In buf
                For x As Integer = (32 - 8) To 0 Step -8
                    rv.Add(CByte((n >> x) And mask))
                Next
            Next
            Return rv.ToArray.PrettyByteBuf(showChar, showDec, showHex, dumpfile, encode)
        End Function
    
        ''' <summary>
        ''' Takes an array and formats it for easier reading.  Shows binary by default.
        ''' </summary>
        ''' <param name="buf">the array</param>
        ''' <param name="showChar">show characters</param>
        ''' <param name="showDec">show decimal</param>
        ''' <param name="showHex">show hex</param>
        ''' <param name="dumpfile">a path string or an open IO.Stream</param>
        ''' <param name="encode">encoding - designed for 7-8 bit character sets</param>
        ''' <returns>formatted string</returns>
        ''' <remarks></remarks>
        <Extension()>
        Public Function PrettyByteBuf(buf() As Long, _
                                      Optional showChar As Boolean = False, _
                                      Optional showDec As Boolean = False, _
                                      Optional showHex As Boolean = False, _
                                      Optional dumpfile As Object = Nothing, _
                                      Optional encode As System.Text.Encoding = Nothing) As String
            Dim rv As New List(Of Byte)
            Dim mask As Byte = &HFF
            For Each n As Long In buf
                For x As Integer = (64 - 8) To 0 Step -8
                    rv.Add(CByte((n >> x) And mask))
                Next
            Next
            Return rv.ToArray.PrettyByteBuf(showChar, showDec, showHex, dumpfile, encode)
        End Function
    
        ''' <summary>
        ''' Takes an array and formats it for easier reading.  Shows binary by default.
        ''' </summary>
        ''' <param name="s">a string</param>
        ''' <param name="showChar">show characters</param>
        ''' <param name="showDec">show decimal</param>
        ''' <param name="showHex">show hex</param>
        ''' <param name="dumpfile">a path string or an open IO.Stream</param>
        ''' <param name="encode">encoding - designed for 7-8 bit character sets</param>
        ''' <returns>formatted string</returns>
        ''' <remarks></remarks>
        <Extension()>
        Public Function PrettyByteBuf(s As String, _
                                      Optional showChar As Boolean = False, _
                                      Optional showDec As Boolean = False, _
                                      Optional showHex As Boolean = False, _
                                      Optional dumpfile As Object = Nothing, _
                                      Optional encode As System.Text.Encoding = Nothing) As String
            Dim rv As New List(Of Byte)
            Dim enc As System.Text.Encoding
            If encode Is Nothing Then
                enc = System.Text.Encoding.Default
            Else
                enc = encode
            End If
            rv.AddRange(enc.GetBytes(s))
            Return rv.ToArray.PrettyByteBuf(showChar, showDec, showHex, dumpfile, encode)
        End Function
    End Module
    Sample output - note that this looks best when formatted to display with a fixed width font

    Code:
    <<--------------0---------1---------2---------3----<>---4---------5---------6---------7--->>
    0         >  00011110  00011111  00100000  00100001  00100010  00100011  00100100  00100101  
    8         >  00100110  00100111  00101000  00101001  00101010  00101011  00101100  00101101  
    16        >  00101110  00101111  00110000  00110001  00110010  00110011  00110100  00110101  
    24        >  00110110  00110111  00111000  00111001  00111010  00111011  00111100  00111101  
    <<--------------0---------1---------2---------3----<>---4---------5---------6---------7--->>
    32        >  00111110  00111111  01000000  01000001  01000010  01000011  01000100  01000101  
    40        >  01000110  01000111  01001000  01001001  01001010  01001011  01001100  01001101  
    48        >  01001110  01001111  01010000  01010001  01010010  01010011  01010100  01010101  
    56        >  01010110  01010111  01011000  01011001  01011010

    Code:
    <<--------------0---------1---------2---------3----<>---4---------5---------6---------7--->>
    0         >  00011110  00011111  00100000  00100001  00100010  00100011  00100100  00100101  
             hex   1E        1F        20        21        22        23        24        25        
             dec   30        31        32        33        34        35        36        37        
              ch   *RS       *US       *SPC      !         "         #         $         %         
    ---------------------------------------------------<>---------------------------------------
    8         >  00100110  00100111  00101000  00101001  00101010  00101011  00101100  00101101  
             hex   26        27        28        29        2A        2B        2C        2D        
             dec   38        39        40        41        42        43        44        45        
              ch   &         '         (         )         *         +         ,         -         
    ---------------------------------------------------<>---------------------------------------
    16        >  00101110  00101111  00110000  00110001  00110010  00110011  00110100  00110101  
             hex   2E        2F        30        31        32        33        34        35        
             dec   46        47        48        49        50        51        52        53        
              ch   .         /         0         1         2         3         4         5         
    ---------------------------------------------------<>---------------------------------------
    24        >  00110110  00110111  00111000  00111001  00111010  00111011  00111100  00111101  
             hex   36        37        38        39        3A        3B        3C        3D        
             dec   54        55        56        57        58        59        60        61        
              ch   6         7         8         9         :         ;         <         =         
    <<--------------0---------1---------2---------3----<>---4---------5---------6---------7--->>
    32        >  00111110  00111111  01000000  01000001  01000010  01000011  01000100  01000101  
             hex   3E        3F        40        41        42        43        44        45        
             dec   62        63        64        65        66        67        68        69        
              ch   >         ?         @         A         B         C         D         E         
    ---------------------------------------------------<>---------------------------------------
    40        >  01000110  01000111  01001000  01001001  01001010  01001011  01001100  01001101  
             hex   46        47        48        49        4A        4B        4C        4D        
             dec   70        71        72        73        74        75        76        77        
              ch   F         G         H         I         J         K         L         M
    Last edited by dbasnett; May 25th, 2015 at 11:04 AM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width