Skip to content

Instantly share code, notes, and snippets.

@vasily-kirichenko
Created October 29, 2014 18:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vasily-kirichenko/1676e8d894eeb849b191 to your computer and use it in GitHub Desktop.
Save vasily-kirichenko/1676e8d894eeb849b191 to your computer and use it in GitHub Desktop.
namespace FSharp.Data
open Microsoft.FSharp.Core.CompilerServices
open ProviderImplementation.ProvidedTypes
open System.Reflection
module internal HexParser =
open System.Text.RegularExpressions
let private getHexVal (hex: char) =
let v = int hex
//For uppercase A-F letters:
v - (if v < 58 then 48 else 55)
let parseString (hex: string) =
if hex.Length % 2 = 1 then
failwith "The binary key cannot have an odd number of digits"
let hex = hex.ToUpper()
if not (Regex.IsMatch (hex, @"^[0-9A-F]+$")) then
failwith "Hex string contains invalid chars"
let arr = Array.zeroCreate (hex.Length >>> 1)
for i = 0 to arr.Length - 1 do
arr.[i] <- byte ((getHexVal (hex.[i <<< 1]) <<< 4) + (getHexVal (hex.[(i <<< 1) + 1])))
arr
[<TypeProvider>]
type HexProvider (_config : TypeProviderConfig) as self =
inherit TypeProviderForNamespaces()
let ns = "FSharp.Data"
let asm = Assembly.GetExecutingAssembly()
let hexType = ProvidedTypeDefinition(asm, ns, "Hex", Some typeof<obj>, HideObjectMethods = true)
let parameters = [ProvidedStaticParameter("HexString", typeof<string>)]
do hexType.DefineStaticParameters(parameters, fun typeName args ->
let root = ProvidedTypeDefinition(asm, ns, typeName, Some typeof<obj>, HideObjectMethods = true)
let hexString = args.[0] :?> string
let arr = HexParser.parseString hexString
let myProp = ProvidedProperty("Value", typeof<byte[]>, IsStatic = true,
GetterCode = (fun _ -> <@@ arr @@>))
root.AddMember(myProp)
root
)
do self.AddNamespace(ns, [hexType])
[<assembly:TypeProviderAssembly>]
do ()
// test
module HexProvider.Test
open FSharp.Data
let a1 = Hex<"0101">.Value
// val a1 : byte [] = [|1uy; 1uy|]
let md5 = Hex<"08494b448aa5b1de963731c21344f803">.Value
// val md5 : byte [] = [|8uy; 73uy; 75uy; 68uy; 138uy; 165uy; 177uy; 222uy; 150uy; 55uy; 49uy; 194uy; 19uy; 68uy; 248uy; 3uy|]
let wrongLen = Hex<"011">
// error FS3033: The type provider 'FSharp.Data.HexProvider' reported an error: The binary key cannot have an odd number of digits
let wrongChars = Hex<"0p">.Value
// error FS3033: The type provider 'FSharp.Data.HexProvider' reported an error: Hex string contains invalid chars
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment