Skip to content

Instantly share code, notes, and snippets.

@matthewcrews
Created January 4, 2024 19:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewcrews/57e83a709d31a6c7fffdd293654c5709 to your computer and use it in GitHub Desktop.
Save matthewcrews/57e83a709d31a6c7fffdd293654c5709 to your computer and use it in GitHub Desktop.
Serialize/Deserialize Binary
open System
open Microsoft.FSharp.Core.LanguagePrimitives
type Weibull_Parameters =
{
Scale: float
Shape: float
}
// Writes the bytes of the parameters to the buffer and returns to new offset for writing
// more data.
static member Encode (p: Weibull_Parameters) =
let scaleBytes = System.BitConverter.GetBytes p.Scale
let shapeBytes = System.BitConverter.GetBytes p.Shape
let result = Array.zeroCreate (scaleBytes.Length + shapeBytes.Length)
scaleBytes.CopyTo (result, 0)
shapeBytes.CopyTo (result, scaleBytes.Length)
result
// Returns a Weibull_Parameters with an updated offset
static member Decode (input: byte[]) (offset: int) =
let scaleBytes = Span(input, offset, sizeof<float>)
let offset = offset + sizeof<float>
let scale = BitConverter.ToDouble scaleBytes
let shapeBytes = Span(input, offset, sizeof<float>)
let offset = offset + sizeof<float>
let shape = BitConverter.ToDouble shapeBytes
let result = {
Scale = scale
Shape = shape
}
result, offset
type Normal_Parameters =
{
Mean: float
StdDev: float
}
// Writes the bytes of the parameters to the buffer and returns to new offset for writing
// more data.
static member Encode (p: Normal_Parameters) =
let meanBytes = System.BitConverter.GetBytes p.Mean
let stdDevBytes = System.BitConverter.GetBytes p.StdDev
let result = Array.zeroCreate (meanBytes.Length + stdDevBytes.Length)
meanBytes.CopyTo (result, 0)
stdDevBytes.CopyTo (result, meanBytes.Length)
result
// Returns a Weibull_Parameters with an updated offset
static member Decode (input: byte[]) (offset: int) =
let meanBytes = Span(input, offset, sizeof<float>)
let offset = offset + sizeof<float>
let scale = BitConverter.ToDouble meanBytes
let stdDevBytes = Span(input, offset, sizeof<float>)
let offset = offset + sizeof<float>
let shape = BitConverter.ToDouble stdDevBytes
let result = {
Mean = scale
StdDev = shape
}
result, offset
// Use byte to encode case of DU
[<RequireQualifiedAccess>]
type Continuous_Distribution_Case =
| Weibull_Parameters = 0uy
| Normal_Parameters = 1uy
[<RequireQualifiedAccess>]
type Continuous_Distribution =
| Weibull_Parameters of Weibull_Parameters
| Normal_Parameters of Normal_Parameters
static member Encode (p: Continuous_Distribution) =
match p with
| Weibull_Parameters wp ->
let data = Weibull_Parameters.Encode wp
let result = Array.zeroCreate (data.Length + 1)
// Set tag byte to 0
result[0] <- EnumToValue Continuous_Distribution_Case.Weibull_Parameters
data.CopyTo (result, 1)
result
| Normal_Parameters np ->
let data = Normal_Parameters.Encode np
let result = Array.zeroCreate (data.Length + 1)
// Set tag byte to 1
result[0] <- EnumToValue Continuous_Distribution_Case.Normal_Parameters
data.CopyTo (result, 1)
result
static member Decode (input: byte[]) (offset: int) =
let case = EnumOfValue input[offset]
// Bump the offset forward
let offset = offset + sizeof<Continuous_Distribution_Case>
match case with
| Continuous_Distribution_Case.Weibull_Parameters ->
let result, offset = Weibull_Parameters.Decode input offset
(Continuous_Distribution.Weibull_Parameters result), offset
| Continuous_Distribution_Case.Normal_Parameters ->
let result, offset = Normal_Parameters.Decode input offset
(Continuous_Distribution.Normal_Parameters result), offset
| _ ->
failwith "Unkown case of Continuous_Distribution_Case"
let x = Continuous_Distribution.Normal_Parameters { Mean = 1.0; StdDev = 2.0 }
let b = Continuous_Distribution.Encode x
let x2 = Continuous_Distribution.Decode b 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment