4 people like it.

ByteString

An initial attempt at creating a ByteString type based on the Haskell version.

ByteString

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
module ByteString

open System
open System.Diagnostics

type ByteString = BS of byte array * int * int with
  static member op_Equality (BS(x,o,l), BS(x',o',l')) =
    if not (l = l') then false
    else (l = 0 && l' = 0) || (x = x' && o = o') // TODO: Add byte by byte comparison
  static member op_Nil = BS(Array.empty,0,0)
  static member op_Cons (hd, BS(x,o,l)) =
    let buffer = Array.zeroCreate<byte> (l + 1)
    Buffer.SetByte(buffer,0,hd)
    Buffer.BlockCopy(x,o,buffer,1,l)
    BS(buffer,0,l+1)
  static member op_Append (BS(x,o,l), BS(x',o',l')) =
    let buffer = Array.zeroCreate<byte> (l + l')
    Buffer.BlockCopy(x,o,buffer,0,l)
    Buffer.BlockCopy(x',o',buffer,l,l')
    BS(buffer,0,l+l')

let empty = ByteString.op_Nil
let singleton c = BS(Array.create 1 c, 0, 1)
let ofList l = BS(Array.ofList l, 0, l.Length)
let toList (BS(x,o,l)) = [ for i in o..l -> x.[i] ]
let isEmpty (BS(_,_,l)) = Debug.Assert(l >= 0); l <= 0
let length (BS(_,_,l)) = Debug.Assert(l >= 0); l
let head (BS(x,o,l)) = if l <= 0 then failwith "" else x.[o]
let tail (BS(x,o,l)) = BS(x,o+1,l-1)
let cons hd tl = ByteString.op_Cons(hd, tl)
let append a b = ByteString.op_Append(a, b)

let split pred l =
  let rec loop l cont =
    if isEmpty l then (empty, empty)
    elif isEmpty (tail l) && not (pred (head l)) then (cont l, empty)
    elif pred (head l) then (cont empty, l)
    elif not (pred (head l)) then loop (tail l) (fun rest -> cont (cons (head l) rest))
    else failwith "ByteString.split: Unrecognized pattern"
  loop l id

let splitAt n l =
  let pred i = i >= n
  let rec loop i l cont =
    if isEmpty l then (empty, empty)
    elif isEmpty (tail l) && not (pred i) then (cont l, empty)
    elif pred i then (cont empty, l)
    elif not (pred i) then loop (i+1) (tail l) (fun rest -> cont (cons (head l) rest))
    else failwith "ByteString.splitAt: Unrecognized pattern"
  loop 0 l id
module ByteString
namespace System
namespace System.Diagnostics
type ByteString =
  | BS of byte array * int * int
  static member ( [] ) : ByteString
  static member ( @ ) : ByteString * ByteString -> ByteString
  static member op_Cons : hd:byte * ByteString -> ByteString
  static member ( = ) : ByteString * ByteString -> bool

Full name: ByteString.ByteString
union case ByteString.BS: byte array * int * int -> ByteString
Multiple items
val byte : value:'T -> byte (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.byte

--------------------
type byte = Byte

Full name: Microsoft.FSharp.Core.byte
type 'T array = 'T []

Full name: Microsoft.FSharp.Core.array<_>
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
val x : byte array
val o : int
val l : int
val x' : byte array
val o' : int
val l' : int
val not : value:bool -> bool

Full name: Microsoft.FSharp.Core.Operators.not
type Array =
  member Clone : unit -> obj
  member CopyTo : array:Array * index:int -> unit + 1 overload
  member GetEnumerator : unit -> IEnumerator
  member GetLength : dimension:int -> int
  member GetLongLength : dimension:int -> int64
  member GetLowerBound : dimension:int -> int
  member GetUpperBound : dimension:int -> int
  member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
  member Initialize : unit -> unit
  member IsFixedSize : bool
  ...

Full name: System.Array
val empty<'T> : 'T []

Full name: Microsoft.FSharp.Collections.Array.empty
static member ByteString.op_Cons : hd:byte * ByteString -> ByteString

Full name: ByteString.ByteString.op_Cons
val hd : byte
val buffer : byte []
val zeroCreate : count:int -> 'T []

Full name: Microsoft.FSharp.Collections.Array.zeroCreate
type Buffer =
  static member BlockCopy : src:Array * srcOffset:int * dst:Array * dstOffset:int * count:int -> unit
  static member ByteLength : array:Array -> int
  static member GetByte : array:Array * index:int -> byte
  static member SetByte : array:Array * index:int * value:byte -> unit

Full name: System.Buffer
Buffer.SetByte(array: Array, index: int, value: byte) : unit
Buffer.BlockCopy(src: Array, srcOffset: int, dst: Array, dstOffset: int, count: int) : unit
val empty : ByteString

Full name: ByteString.empty
property ByteString.op_Nil: ByteString
val singleton : c:byte -> ByteString

Full name: ByteString.singleton
val c : byte
val create : count:int -> value:'T -> 'T []

Full name: Microsoft.FSharp.Collections.Array.create
val ofList : l:byte list -> ByteString

Full name: ByteString.ofList
val l : byte list
val ofList : list:'T list -> 'T []

Full name: Microsoft.FSharp.Collections.Array.ofList
property List.Length: int
val toList : ByteString -> byte list

Full name: ByteString.toList
val i : int
val isEmpty : ByteString -> bool

Full name: ByteString.isEmpty
type Debug =
  static member Assert : condition:bool -> unit + 3 overloads
  static member AutoFlush : bool with get, set
  static member Close : unit -> unit
  static member Fail : message:string -> unit + 1 overload
  static member Flush : unit -> unit
  static member Indent : unit -> unit
  static member IndentLevel : int with get, set
  static member IndentSize : int with get, set
  static member Listeners : TraceListenerCollection
  static member Print : message:string -> unit + 1 overload
  ...

Full name: System.Diagnostics.Debug
Debug.Assert(condition: bool) : unit
Debug.Assert(condition: bool, message: string) : unit
Debug.Assert(condition: bool, message: string, detailMessage: string) : unit
Debug.Assert(condition: bool, message: string, detailMessageFormat: string, [<ParamArray>] args: obj []) : unit
val length : ByteString -> int

Full name: ByteString.length
val head : ByteString -> byte

Full name: ByteString.head
val failwith : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.failwith
val tail : ByteString -> ByteString

Full name: ByteString.tail
val cons : hd:byte -> tl:ByteString -> ByteString

Full name: ByteString.cons
val tl : ByteString
static member ByteString.op_Cons : hd:byte * ByteString -> ByteString
val append : a:ByteString -> b:ByteString -> ByteString

Full name: ByteString.append
val a : ByteString
val b : ByteString
static member ByteString.( @ ) : ByteString * ByteString -> ByteString
val split : pred:(byte -> bool) -> l:ByteString -> ByteString * ByteString

Full name: ByteString.split
val pred : (byte -> bool)
val l : ByteString
val loop : (ByteString -> (ByteString -> ByteString) -> ByteString * ByteString)
val cont : (ByteString -> ByteString)
val rest : ByteString
val id : x:'T -> 'T

Full name: Microsoft.FSharp.Core.Operators.id
val splitAt : n:int -> l:ByteString -> ByteString * ByteString

Full name: ByteString.splitAt
val n : int
val pred : (int -> bool)
val loop : (int -> ByteString -> (ByteString -> ByteString) -> ByteString * ByteString)
Next Version Raw view Test code New version

More information

Link:http://fssnip.net/6B
Posted:12 years ago
Author:Ryan Riley
Tags: bytestring , stream , list , sequence , arraysegment