Skip to content
This repository has been archived by the owner on Oct 31, 2021. It is now read-only.

Commit

Permalink
- DecoderContext.ReadByte returns the byte value rather than an array…
Browse files Browse the repository at this point in the history
… segment
  • Loading branch information
theburningmonk committed Jan 12, 2014
1 parent 06548c0 commit c35362e
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 17 deletions.
4 changes: 2 additions & 2 deletions Filbert.sln
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ Global
{0035839E-C9B3-4153-8689-00D3B1251A26}.Release|x86.ActiveCfg = Release|Any CPU
{2EC7E114-9DB5-4AC0-9550-B4239B4BA946}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2EC7E114-9DB5-4AC0-9550-B4239B4BA946}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2EC7E114-9DB5-4AC0-9550-B4239B4BA946}.Debug|Mixed Platforms.ActiveCfg = Release|Any CPU
{2EC7E114-9DB5-4AC0-9550-B4239B4BA946}.Debug|Mixed Platforms.Build.0 = Release|Any CPU
{2EC7E114-9DB5-4AC0-9550-B4239B4BA946}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{2EC7E114-9DB5-4AC0-9550-B4239B4BA946}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{2EC7E114-9DB5-4AC0-9550-B4239B4BA946}.Debug|x86.ActiveCfg = Debug|Any CPU
{2EC7E114-9DB5-4AC0-9550-B4239B4BA946}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2EC7E114-9DB5-4AC0-9550-B4239B4BA946}.Release|Any CPU.Build.0 = Release|Any CPU
Expand Down
17 changes: 7 additions & 10 deletions src/Filbert/Decoder.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ open Checked

[<AutoOpen>]
module ArraySegmentReaders =
/// Reads a single byte
let inline byteReader (seg : ArraySegment<byte>) = seg.Array.[seg.Offset]

/// Reads some bytes into an array
let inline byteArrayReader n (seg : ArraySegment<byte>) =
let arr = Array.zeroCreate<byte> n
Expand Down Expand Up @@ -53,7 +50,7 @@ let inline readBigInt n (ctx : DecoderContext) =
let bigInteger (buffer : byte[]) =
buffer |> Seq.mapi (fun i digit -> (byteToBigInt digit) * (256I ** i)) |> Seq.sum

let sign = ctx.ReadByte() |> byteReader |> function | 0uy -> 1I | 1uy -> -1I
let sign = ctx.ReadByte() |> function | 0uy -> 1I | 1uy -> -1I
ctx.ReadBytes n |> byteArrayReader n |> bigInteger |> (fun n -> n * sign)

/// Converts a set of megasecond, second and microsecond values into a DateTime value
Expand All @@ -62,7 +59,7 @@ let inline toDateTime (mega : int) (sec :int) (micro : int) =

[<AutoOpen>]
module Decoders =
let decodeSmallInt = byteReader >> int >> Integer
let decodeSmallInt = int >> Integer
let decodeInt = byteArrayReader 4 >> bigEndianInteger >> Integer
let decodeFloat = byteArrayReader 31 >> str >> float >> Float
let decodeUint = byteArrayReader 4 >> bigEndianUinteger
Expand Down Expand Up @@ -91,7 +88,7 @@ let inline readComplexBert (items : Bert[]) =
/// Parses the Erlang External Term Format
/// see http://erlang.org/doc/apps/erts/erl_ext_dist.html
let rec decodeType (ctx : DecoderContext) : Bert =
match byteReader <| ctx.ReadByte() with
match ctx.ReadByte() with
// SMALL_INTEGER (unsigned 8 bit integer)
| Tags.smallInteger -> ctx.ReadByte() |> decodeSmallInt
// INTEGER (32 bit integer in big-endian format)
Expand All @@ -105,7 +102,7 @@ let rec decodeType (ctx : DecoderContext) : Bert =
| 0 -> raise <| InvalidAtomLength len
| n -> ctx.ReadBytes len |> byteArrayReader len |> str |> Atom
// SMALL_TUPLE
| Tags.smallTuple -> let arity = ctx.ReadByte() |> byteReader |> int
| Tags.smallTuple -> let arity = ctx.ReadByte() |> int
match arity with
| 0 -> [||] |> Tuple
| n -> ctx |> readTuple n
Expand All @@ -126,7 +123,7 @@ let rec decodeType (ctx : DecoderContext) : Bert =
// as per specified by LIST_EXT, it should end with NIL_EXT for a
// proper list, for simplicity sake, for now impropert list is not
// going to be supported here
match ctx.ReadByte() |> byteReader with
match ctx.ReadByte() with
| Tags.nil -> List berts
| _ -> raise ImpropertyListNotSupported
// BINARY
Expand All @@ -135,7 +132,7 @@ let rec decodeType (ctx : DecoderContext) : Bert =
| 0 -> Binary [||]
| n -> ctx.ReadBytes n |> byteArrayReader n |> Binary
// SMALL_BIG
| Tags.smallBig -> let n = ctx.ReadByte() |> byteReader |> int
| Tags.smallBig -> let n = ctx.ReadByte() |> int
ctx |> readBigInt n |> BigInteger
// LARGE_BIG
| Tags.largeBig -> let n = ctx.ReadBytes 4 |> decodeUint |> int
Expand All @@ -160,6 +157,6 @@ and readTuple arity (ctx : DecoderContext) =

let decode (stream : Stream) =
use ctx = new DecoderContext(stream)
match byteReader <| ctx.ReadByte() with
match ctx.ReadByte() with
| Constants.version -> decodeType ctx
| n -> raise <| InvalidVersion n
10 changes: 9 additions & 1 deletion src/Filbert/Utils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,16 @@ type internal DecoderContext (stream : Stream) =
swapBuffer()
if n > bufferSize then raise <| InsufficientNumberOfBytes(n, bufferSize)
readBytes n

let readByte () =
if bufferSize = 0 then raise <| InsufficientNumberOfBytes(1, bufferSize)
if index = bufferSize then initBuffer()
try
buffer.[index]
finally
index <- index + 1

member this.ReadByte() = readBytes 1
member this.ReadByte() = readByte()

member this.ReadBytes(n) = readBytes n

Expand Down
8 changes: 4 additions & 4 deletions tests/Filbert.Tests/DecoderContext.fs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ type ``Given a decoder context`` () =
use memStream = new MemoryStream(input)
use ctx = new DecoderContext(memStream)

ctx.ReadByte() |> should equal <| new ArraySegment<byte>(input, 0, 1)
ctx.ReadByte() |> should equal <| new ArraySegment<byte>(input, 1, 1)
ctx.ReadByte() |> should equal <| new ArraySegment<byte>(input, 2, 1)
ctx.ReadByte() |> should equal <| 1uy
ctx.ReadByte() |> should equal <| 2uy
ctx.ReadByte() |> should equal <| 3uy

[<Test>]
member test.``when there is sufficient data in the stream, read bytes should return them all`` () =
Expand All @@ -52,7 +52,7 @@ type ``Given a decoder context`` () =
use memStream = new MemoryStream(input)
use ctx = new DecoderContext(memStream)

ctx.ReadByte() |> should equal <| new ArraySegment<byte>(input, 0, 1)
ctx.ReadByte() |> should equal 1uy
ctx.ReadBytes 1024 |> should equal <| new ArraySegment<byte>(input, 1, 1024)

[<Test>]
Expand Down
1 change: 1 addition & 0 deletions tests/Filbert.Tests/Filbert.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
<ItemGroup>
<Compile Include="BufferPool.fs" />
<Compile Include="DecoderContext.fs" />
<Compile Include="Encoder.fs" />
<Compile Include="Decoder.fs" />
<None Include="packages.config" />
Expand Down

0 comments on commit c35362e

Please sign in to comment.