hexquote-0.1: Hexadecimal ByteString literals, with placeholders that bind variables

Data.Hex.Quote

Contents

Description

Provides a quasiquoter for hexadecimal ByteString literals, with placeholders that bind variables.

Synopsis

The quasiquoter

hex :: QuasiQuoterSource

As an expression, the hex quasiquoter provides hexadecimal ByteString literals:

import Data.Hex.Quote
import qualified Data.ByteString as B

main = B.putStr [hex|
    57 65 2c 20 61 6c 6f 6e 65 20 6f 6e 20 65 61 72
    74 68 2c 20 63 61 6e 20 72 65 62 65 6c 20 61 67
    61 69 6e 73 74 20 74 68 65 20 74 79 72 61 6e 6e
    79 20 6f 66 20 74 68 65 20 73 65 6c 66 69 73 68
    20 72 65 70 6c 69 63 61 74 6f 72 73 2e 0a |]

All characters other than 0123456789abcdefABCDEF are ignored, including whitespace. Comments start with "--" and continue to end-of-line:

code = [hex|
    7e3a          -- jle  0x3c
    4889f5        -- mov  rbp, rsi
    bb01000000    -- mov  ebx, 0x1
    488b7d08 |]   -- mov  rdi, [rbp+0x8]

When using hex as a pattern, you can include placeholders of the form <name:size>, where

  • name is a Haskell identifier, or the wildcard pattern "_"
  • size is the size of the field in bytes, or the word rest to consume the rest of the ByteString.

The named placeholders bind local variables of type ByteString. Here's an example of pattern-matching an IPv4-over-Ethernet-II frame:

import Data.Hex.Quote

describe [hex|
    <src_mac:6> <dst_mac:6> 08 00  -- ethernet header
    45 <_:1> <len:2>               -- start of IP header
    <_:rest>                       -- discard remaining frame
  |] = (src_mac, dst_mac, len)

describe _ = error "unknown frame"

Quasiquotes require the QuasiQuotes extension. In pattern context, hex also requires the ViewPatterns extension.

Helper functions

parseHex :: String -> [Word8]Source

The hexadecimal parser used for hex expressions.