├── .gitignore
├── UpgradeLog.htm
├── .nuget
├── NuGet.exe
├── NuGet.Config
└── NuGet.targets
├── appveyor.yml
├── MsgPack.Test
├── lib
│ └── nunit.framework.dll
├── Extensions.fs
├── MsgPack.Test.fsproj
├── UnpackerTest.fs
└── PackerTest.fs
├── MsgPackPCL
├── Script.fsx
└── MsgPackPCL.fsproj
├── README.rst
├── MsgPack.sln
├── MsgPack
├── MsgPack.fsproj
├── MsgPack.fs
├── Packer.fs
└── Unpacker.fs
└── LICENSE.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | MsgPack.v11.suo
2 | bin/
3 | obj/
4 |
--------------------------------------------------------------------------------
/UpgradeLog.htm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gab-km/msgpack-fsharp/HEAD/UpgradeLog.htm
--------------------------------------------------------------------------------
/.nuget/NuGet.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gab-km/msgpack-fsharp/HEAD/.nuget/NuGet.exe
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | branches:
2 | except:
3 | - gh-pages
4 |
5 | test:
6 | assemblies:
7 | - MsgPack.Test.dll
8 |
--------------------------------------------------------------------------------
/MsgPack.Test/lib/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Gab-km/msgpack-fsharp/HEAD/MsgPack.Test/lib/nunit.framework.dll
--------------------------------------------------------------------------------
/.nuget/NuGet.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/MsgPackPCL/Script.fsx:
--------------------------------------------------------------------------------
1 | // Learn more about F# at http://fsharp.net. See the 'F# Tutorial' project
2 | // for more guidance on F# programming.
3 |
4 | #load "PortableLibrary1.fs"
5 | open MsgPackPCL
6 |
7 |
--------------------------------------------------------------------------------
/MsgPack.Test/Extensions.fs:
--------------------------------------------------------------------------------
1 | namespace MsgPack.Test
2 |
3 | open NUnit.Framework
4 |
5 | module Extensions =
6 |
7 | let assertEqualTo<'a> (expected: 'a) (actual: 'a) = Assert.That(actual, Is.EqualTo(expected))
8 | let assertEquivalentTo<'a> expected (actual: 'a) = Assert.That(actual, Is.EquivalentTo(expected))
9 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | MessagePack for F#
2 | ==================
3 |
4 | .. image:: https://ci.appveyor.com/api/projects/status/qghqrl7nwq96aval
5 | :target: https://ci.appveyor.com/project/Gabkm/msgpack-fsharp
6 | :alt: Build status
7 |
8 | What is this?
9 | -------------
10 |
11 | MessagePack is a fast and compact binary serialization library.
12 |
13 | MessagePack for F# is a MessagePack implementation of F#, by F#, for F#.
14 |
15 | Usage
16 | -----
17 |
18 | .. code-block:: fsharp
19 |
20 | open MsgPack
21 |
22 | [| 1uy; 2uy; 3uy |]
23 | |> Array.map (Value.UInt8)
24 | |> Value.Array
25 | |> Packer.packOne
26 | //=> val it : byte [] = [|147uy; 1uy; 2uy; 3uy|]
27 |
28 | Unpacker.unpack [|147uy; 1uy; 2uy; 3uy|]
29 | //=> [|Value.Array [|Value.UInt8 1uy; Value.UInt8 2uy; Value.UInt8 3uy|]|]
30 |
31 | Copyright
32 | ---------
33 |
34 | ``Copyright (c) 2014- Kazuhiro Matsushima``
35 |
36 | License
37 | -------
38 |
39 | Distributed under the `Apache License, Version 2.0 `_ .
40 |
--------------------------------------------------------------------------------
/MsgPack.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.31101.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{5F71D702-F628-4A84-87DD-98DB3CF19068}"
7 | ProjectSection(SolutionItems) = preProject
8 | .nuget\NuGet.Config = .nuget\NuGet.Config
9 | .nuget\NuGet.exe = .nuget\NuGet.exe
10 | .nuget\NuGet.targets = .nuget\NuGet.targets
11 | EndProjectSection
12 | EndProject
13 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MsgPack", "MsgPack\MsgPack.fsproj", "{6A301137-4611-40FC-A07C-D78179AB446C}"
14 | EndProject
15 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MsgPack.Test", "MsgPack.Test\MsgPack.Test.fsproj", "{857ABED7-F0CB-4579-986F-2978261CFD0F}"
16 | ProjectSection(ProjectDependencies) = postProject
17 | {6A301137-4611-40FC-A07C-D78179AB446C} = {6A301137-4611-40FC-A07C-D78179AB446C}
18 | EndProjectSection
19 | EndProject
20 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MsgPackPCL", "MsgPackPCL\MsgPackPCL.fsproj", "{963773D4-D2EE-48D3-86C4-DC44376ABF27}"
21 | EndProject
22 | Global
23 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
24 | Debug|Any CPU = Debug|Any CPU
25 | Release|Any CPU = Release|Any CPU
26 | EndGlobalSection
27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
28 | {6A301137-4611-40FC-A07C-D78179AB446C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29 | {6A301137-4611-40FC-A07C-D78179AB446C}.Debug|Any CPU.Build.0 = Debug|Any CPU
30 | {6A301137-4611-40FC-A07C-D78179AB446C}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {6A301137-4611-40FC-A07C-D78179AB446C}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {857ABED7-F0CB-4579-986F-2978261CFD0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33 | {857ABED7-F0CB-4579-986F-2978261CFD0F}.Debug|Any CPU.Build.0 = Debug|Any CPU
34 | {857ABED7-F0CB-4579-986F-2978261CFD0F}.Release|Any CPU.ActiveCfg = Release|Any CPU
35 | {857ABED7-F0CB-4579-986F-2978261CFD0F}.Release|Any CPU.Build.0 = Release|Any CPU
36 | {963773D4-D2EE-48D3-86C4-DC44376ABF27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37 | {963773D4-D2EE-48D3-86C4-DC44376ABF27}.Debug|Any CPU.Build.0 = Debug|Any CPU
38 | {963773D4-D2EE-48D3-86C4-DC44376ABF27}.Release|Any CPU.ActiveCfg = Release|Any CPU
39 | {963773D4-D2EE-48D3-86C4-DC44376ABF27}.Release|Any CPU.Build.0 = Release|Any CPU
40 | EndGlobalSection
41 | GlobalSection(SolutionProperties) = preSolution
42 | HideSolutionNode = FALSE
43 | EndGlobalSection
44 | EndGlobal
45 |
--------------------------------------------------------------------------------
/MsgPackPCL/MsgPackPCL.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | 2.0
8 | 963773d4-d2ee-48d3-86c4-dc44376abf27
9 | Library
10 | MsgPackPCL
11 | MsgPackPCL
12 | v4.5
13 | Profile7
14 | netcore
15 | 3.3.1.0
16 | MsgPackPCL
17 |
18 |
19 | true
20 | full
21 | false
22 | false
23 | bin\Debug\
24 | DEBUG;TRACE
25 | 3
26 | bin\Debug\MsgPackPCL.XML
27 |
28 |
29 | pdbonly
30 | true
31 | true
32 | bin\Release\
33 | TRACE
34 | 3
35 | bin\Release\MsgPackPCL.XML
36 |
37 |
38 | 12
39 |
40 |
41 |
42 |
43 |
44 | MsgPack.fs
45 |
46 |
47 | Packer.fs
48 |
49 |
50 | Unpacker.fs
51 |
52 |
53 |
54 |
55 | FSharp.Core
56 | FSharp.Core.dll
57 | $(MSBuildExtensionsPath32)\..\Reference Assemblies\Microsoft\FSharp\.NETCore\$(TargetFSharpCoreVersion)\FSharp.Core.dll
58 |
59 |
60 |
67 |
--------------------------------------------------------------------------------
/MsgPack/MsgPack.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | 2.0
8 | 6a301137-4611-40fc-a07c-d78179ab446c
9 | Library
10 | MsgPack
11 | MsgPack
12 | v4.5
13 | MsgPack
14 | 4.3.0.0
15 |
16 |
17 | true
18 | full
19 | false
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | 3
24 | bin\Debug\MsgPack.XML
25 | false
26 |
27 |
28 | pdbonly
29 | true
30 | true
31 | bin\Release\
32 | TRACE
33 | 3
34 | bin\Release\MsgPack.XML
35 |
36 |
37 |
38 | True
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | 11
52 |
53 |
54 |
55 |
56 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets
57 |
58 |
59 |
60 |
61 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets
62 |
63 |
64 |
65 |
66 |
73 |
--------------------------------------------------------------------------------
/MsgPack.Test/MsgPack.Test.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | 2.0
8 | 857abed7-f0cb-4579-986f-2978261cfd0f
9 | Library
10 | MsgPack.Test
11 | MsgPack.Test
12 | v4.5
13 | MsgPack.Test
14 | 4.3.0.0
15 |
16 |
17 | true
18 | full
19 | false
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | 3
24 | bin\Debug\MsgPack.Test.XML
25 | Project
26 |
27 |
28 |
29 |
30 |
31 |
32 | pdbonly
33 | true
34 | true
35 | bin\Release\
36 | TRACE
37 | 3
38 | bin\Release\MsgPack.Test.XML
39 |
40 |
41 |
42 | True
43 |
44 |
45 |
46 | lib\nunit.framework.dll
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | MsgPack
60 | {6a301137-4611-40fc-a07c-d78179ab446c}
61 | True
62 |
63 |
64 |
65 | 11
66 |
67 |
68 |
69 |
70 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets
71 |
72 |
73 |
74 |
75 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets
76 |
77 |
78 |
79 |
80 |
87 |
--------------------------------------------------------------------------------
/MsgPack/MsgPack.fs:
--------------------------------------------------------------------------------
1 | #nowarn "9"
2 |
3 | namespace MsgPack
4 |
5 | type Value =
6 | | Nil
7 | | Bool of bool
8 | | Float32 of float32
9 | | Float64 of float
10 | | UInt8 of byte
11 | | UInt16 of uint16
12 | | UInt32 of uint32
13 | | UInt64 of uint64
14 | | Int8 of sbyte
15 | | Int16 of int16
16 | | Int32 of int
17 | | Int64 of int64
18 | | String of string
19 | | Bin of byte []
20 | | Array of Value []
21 | | Map of Map
22 | | Ext of sbyte * byte []
23 | override self.ToString() =
24 | match self with
25 | | Nil -> "Nil"
26 | | Bool (b) -> "Bool " + (b.ToString())
27 | | Float32 (f) -> "Float32 " + (f.ToString())
28 | | Float64 (d) -> "Float64 " + (d.ToString())
29 | | UInt8 (u) -> "UInt8 " + (u.ToString())
30 | | UInt16 (u) -> "UInt16 " + (u.ToString())
31 | | UInt32 (u) -> "UInt32 " + (u.ToString())
32 | | UInt64 (u) -> "UInt64 " + (u.ToString())
33 | | Int8 (i) -> "Int8 " + (i.ToString())
34 | | Int16 (i) -> "Int16 " + (i.ToString())
35 | | Int32 (i) -> "Int32 " + (i.ToString())
36 | | Int64 (i) -> "Int64 " + (i.ToString())
37 | | String (s) -> "String " + s
38 | | Bin (bs) -> sprintf "%A" bs
39 | | Array (ar) -> sprintf "%A" ar
40 | | Map (m) -> "Map " + (m.ToString())
41 | | Ext (key, value) -> "Ext " + (key, value).ToString()
42 |
43 | type Format =
44 | static member Nil = 0xC0uy
45 | static member False = 0xC2uy
46 | static member True = 0xC3uy
47 | static member Bin8 = 0xC4uy
48 | static member Bin16 = 0xC5uy
49 | static member Bin32 = 0xC6uy
50 | static member Ext8 = 0xC7uy
51 | static member Ext16 = 0xC8uy
52 | static member Ext32 = 0xC9uy
53 | static member Float32 = 0xCAuy
54 | static member Float64 = 0xCBuy
55 | static member UInt8 = 0xCCuy
56 | static member UInt16 = 0xCDuy
57 | static member UInt32 = 0xCEuy
58 | static member UInt64 = 0xCFuy
59 | static member Int8 = 0xD0uy
60 | static member Int16 = 0xD1uy
61 | static member Int32 = 0xD2uy
62 | static member Int64 = 0xD3uy
63 | static member FixExt1 = 0xD4uy
64 | static member FixExt2 = 0xD5uy
65 | static member FixExt4 = 0xD6uy
66 | static member FixExt8 = 0xD7uy
67 | static member FixExt16 = 0xD8uy
68 | static member Str8 = 0xD9uy
69 | static member Str16 = 0xDAuy
70 | static member Str32 = 0xDBuy
71 | static member Array16 = 0xDCuy
72 | static member Array32 = 0xDDuy
73 | static member Map16 = 0xDEuy
74 | static member Map32 = 0xDFuy
75 |
76 | type MessagePackException(message : string) =
77 | inherit System.Exception(message)
78 |
79 | module internal Utility =
80 | open System.Runtime.InteropServices
81 | []
82 | type internal Float32 =
83 | []val mutable Value: float32
84 | [][]val mutable Byte0: byte
85 | [][]val mutable Byte1: byte
86 | [][]val mutable Byte2: byte
87 | [][]val mutable Byte3: byte
88 | member self.ToBytes(isLittleEndian) =
89 | if isLittleEndian then [| self.Byte3; self.Byte2; self.Byte1; self.Byte0 |]
90 | else [| self.Byte0; self.Byte1; self.Byte2; self.Byte3 |]
91 |
92 | []
93 | type internal Float =
94 | []val mutable Value: float
95 | []val mutable Byte0: byte
96 | []val mutable Byte1: byte
97 | []val mutable Byte2: byte
98 | []val mutable Byte3: byte
99 | []val mutable Byte4: byte
100 | []val mutable Byte5: byte
101 | []val mutable Byte6: byte
102 | []val mutable Byte7: byte
103 | member self.ToBytes(isLittleEndian) =
104 | if isLittleEndian then [| self.Byte7; self.Byte6; self.Byte5; self.Byte4; self.Byte3; self.Byte2; self.Byte1; self.Byte0|]
105 | else [| self.Byte0; self.Byte1; self.Byte2; self.Byte3; self.Byte4; self.Byte5; self.Byte6; self.Byte7 |]
106 |
107 | []
108 | let convertEndianFromFloat32ToBytes (value: float32) =
109 | let f = Float32(Value=value)
110 | f.ToBytes(System.BitConverter.IsLittleEndian)
111 |
112 | []
113 | let convertEndianFromFloatToBytes (value: float) =
114 | let d = Float(Value=value)
115 | d.ToBytes(System.BitConverter.IsLittleEndian)
116 |
117 | []
118 | let convertEndianFromBytesToFloat32 (bs: byte[]) =
119 | let f =
120 | if System.BitConverter.IsLittleEndian then
121 | Float32(
122 | Byte0 = (if bs.Length >= 4 then bs.[3] else 0uy),
123 | Byte1 = (if bs.Length >= 3 then bs.[2] else 0uy),
124 | Byte2 = (if bs.Length >= 2 then bs.[1] else 0uy),
125 | Byte3 = (if bs.Length >= 1 then bs.[0] else 0uy))
126 | else
127 | Float32(
128 | Byte0 = (if bs.Length >= 1 then bs.[0] else 0uy),
129 | Byte1 = (if bs.Length >= 2 then bs.[1] else 0uy),
130 | Byte2 = (if bs.Length >= 3 then bs.[2] else 0uy),
131 | Byte3 = (if bs.Length >= 4 then bs.[3] else 0uy))
132 | f.Value
133 |
134 | []
135 | let convertEndianFromBytesToFloat (bs: byte[]) =
136 | let d =
137 | if System.BitConverter.IsLittleEndian then
138 | Float(
139 | Byte0 = (if bs.Length >= 8 then bs.[7] else 0uy),
140 | Byte1 = (if bs.Length >= 7 then bs.[6] else 0uy),
141 | Byte2 = (if bs.Length >= 6 then bs.[5] else 0uy),
142 | Byte3 = (if bs.Length >= 5 then bs.[4] else 0uy),
143 | Byte4 = (if bs.Length >= 4 then bs.[3] else 0uy),
144 | Byte5 = (if bs.Length >= 3 then bs.[2] else 0uy),
145 | Byte6 = (if bs.Length >= 2 then bs.[1] else 0uy),
146 | Byte7 = (if bs.Length >= 1 then bs.[0] else 0uy))
147 | else
148 | Float(
149 | Byte0 = (if bs.Length >= 1 then bs.[0] else 0uy),
150 | Byte1 = (if bs.Length >= 2 then bs.[1] else 0uy),
151 | Byte2 = (if bs.Length >= 3 then bs.[2] else 0uy),
152 | Byte3 = (if bs.Length >= 4 then bs.[3] else 0uy),
153 | Byte4 = (if bs.Length >= 5 then bs.[4] else 0uy),
154 | Byte5 = (if bs.Length >= 6 then bs.[5] else 0uy),
155 | Byte6 = (if bs.Length >= 7 then bs.[6] else 0uy),
156 | Byte7 = (if bs.Length >= 8 then bs.[7] else 0uy))
157 | d.Value
158 |
--------------------------------------------------------------------------------
/.nuget/NuGet.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildProjectDirectory)\..\
5 |
6 |
7 | false
8 |
9 |
10 | false
11 |
12 |
13 | true
14 |
15 |
16 | false
17 |
18 |
19 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
30 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget"))
31 |
32 |
33 |
34 |
35 | $(SolutionDir).nuget
36 |
37 |
38 |
39 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config
40 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config
41 |
42 |
43 |
44 | $(MSBuildProjectDirectory)\packages.config
45 | $(PackagesProjectConfig)
46 |
47 |
48 |
49 |
50 | $(NuGetToolsPath)\NuGet.exe
51 | @(PackageSource)
52 |
53 | "$(NuGetExePath)"
54 | mono --runtime=v4.0.30319 "$(NuGetExePath)"
55 |
56 | $(TargetDir.Trim('\\'))
57 |
58 | -RequireConsent
59 | -NonInteractive
60 |
61 | "$(SolutionDir) "
62 | "$(SolutionDir)"
63 |
64 |
65 | $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)
66 | $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols
67 |
68 |
69 |
70 | RestorePackages;
71 | $(BuildDependsOn);
72 |
73 |
74 |
75 |
76 | $(BuildDependsOn);
77 | BuildPackage;
78 |
79 |
80 |
81 |
82 |
83 |
84 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
99 |
100 |
103 |
104 |
105 |
106 |
108 |
109 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
141 |
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright (C) 2014 Kazuhiro Matsushima
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/MsgPack/Packer.fs:
--------------------------------------------------------------------------------
1 | namespace MsgPack
2 |
3 | module Packer =
4 | []
5 | let packBool value =
6 | if value then
7 | [| Format.True |]
8 | else
9 | [| Format.False |]
10 |
11 | []
12 | let packByte value =
13 | if value < (1uy <<< 7) then
14 | [| byte value |]
15 | else
16 | [| Format.UInt8
17 | byte value |]
18 |
19 | []
20 | let packUInt16 value =
21 | if value < (1us <<< 8) then
22 | if value < (1us <<< 7) then
23 | [| byte value |]
24 | else
25 | [| Format.UInt8
26 | byte value |]
27 | else
28 | [| Format.UInt16
29 | byte (value >>> 8)
30 | byte (value &&& 0x00FFus) |]
31 |
32 | []
33 | let packUInt32 value =
34 | if value < (1u <<< 8) then
35 | if value < (1u <<< 7) then
36 | [| byte value |]
37 | else
38 | [| Format.UInt8
39 | byte value |]
40 | else
41 | if value < (1u <<< 16) then
42 | [| Format.UInt16
43 | byte (value >>> 8)
44 | byte (value &&& 0x00FFu) |]
45 | else
46 | [| Format.UInt32
47 | byte (value >>> 24)
48 | byte ((value &&& 0x00FF0000u) >>> 16)
49 | byte ((value &&& 0x0000FF00u) >>> 8)
50 | byte (value &&& 0x000000FFu) |]
51 |
52 | []
53 | let packUInt64 value =
54 | if value < (1UL <<< 8) then
55 | if value < (1UL <<< 7)
56 | then [| byte value |]
57 | else
58 | [| Format.UInt8
59 | byte value |]
60 | else
61 | if value < (1UL <<< 16) then
62 | [| Format.UInt16
63 | byte (value >>> 8)
64 | byte (value &&& 0x00FFUL) |]
65 | elif value < (1UL <<< 32) then
66 | [| Format.UInt32
67 | byte (value >>> 24)
68 | byte ((value &&& 0x00FF0000UL) >>> 16)
69 | byte ((value &&& 0x0000FF00UL) >>> 8)
70 | byte (value &&& 0x000000FFUL) |]
71 | else
72 | [| Format.UInt64
73 | byte (value >>> 56)
74 | byte ((value &&& 0x00FF000000000000UL) >>> 48)
75 | byte ((value &&& 0x0000FF0000000000UL) >>> 40)
76 | byte ((value &&& 0x000000FF00000000UL) >>> 32)
77 | byte ((value &&& 0x00000000FF000000UL) >>> 24)
78 | byte ((value &&& 0x0000000000FF0000UL) >>> 16)
79 | byte ((value &&& 0x000000000000FF00UL) >>> 8)
80 | byte (value &&& 0x00000000000000FFUL) |]
81 |
82 | []
83 | let packSByte value =
84 | if value < -(1y <<< 5) then
85 | [| Format.Int8
86 | byte value |]
87 | else
88 | [| byte value |]
89 |
90 | []
91 | let packInt16 value =
92 | if value < -(1s <<< 5) then
93 | if value < -(1s <<< 7) then
94 | [| Format.Int16
95 | byte (value >>> 8)
96 | byte (value &&& 0x00FFs) |]
97 | else
98 | [| Format.Int8
99 | byte value |]
100 | elif value < (1s <<< 7) then
101 | // fixnum
102 | [| byte value |]
103 | else
104 | value |> uint16 |> packUInt16
105 |
106 | []
107 | let packInt value =
108 | if value < -(1 <<< 5) then
109 | if value < -(1 <<< 15) then
110 | [| Format.Int32
111 | byte (value >>> 24)
112 | byte ((value &&& 0x00FF0000) >>> 16)
113 | byte ((value &&& 0x0000FF00) >>> 8)
114 | byte (value &&& 0x000000FF) |]
115 | elif value < -(1 <<< 7) then
116 | [| Format.Int16
117 | byte (value >>> 8)
118 | byte (value &&& 0x00FF) |]
119 | else
120 | [| Format.Int8
121 | byte value |]
122 | elif value < (1 <<< 7) then
123 | // fixnum
124 | [| byte value |]
125 | else
126 | value |> uint32 |> packUInt32
127 |
128 | []
129 | let packInt64 value =
130 | if value < -(1L <<< 5) then
131 | if value < -(1L <<< 15) then
132 | if value < -(1L <<< 31) then
133 | [| Format.Int64
134 | byte (value >>> 56)
135 | byte ((value &&& 0x00FF000000000000L) >>> 48)
136 | byte ((value &&& 0x0000FF0000000000L) >>> 40)
137 | byte ((value &&& 0x000000FF00000000L) >>> 32)
138 | byte ((value &&& 0x00000000FF000000L) >>> 24)
139 | byte ((value &&& 0x0000000000FF0000L) >>> 16)
140 | byte ((value &&& 0x000000000000FF00L) >>> 8)
141 | byte (value &&& 0x00000000000000FFL) |]
142 | else
143 | value |> int32 |> packInt
144 | else
145 | value |> int32 |> packInt
146 | elif value < (1L <<< 7) then
147 | // fixnum
148 | [| byte value |]
149 | else
150 | value |> uint64 |> packUInt64
151 |
152 | []
153 | let packFloat32 (value: float32) =
154 | Array.append [| Format.Float32 |] (Utility.convertEndianFromFloat32ToBytes value)
155 |
156 | []
157 | let packFloat (value: float) =
158 | Array.append [| Format.Float64 |] (Utility.convertEndianFromFloatToBytes value)
159 |
160 | []
161 | let packNil () =
162 | [| Format.Nil |]
163 |
164 | []
165 | let packString (value: string) =
166 | let bytes = System.Text.Encoding.UTF8.GetBytes(value)
167 | let length = bytes.Length
168 | let (|FixStr|_|) (length: int) =
169 | if length < 32 then Some(length)
170 | else None
171 | let (|Str8|_|) (length: int) =
172 | if length < 0xFF then Some(length)
173 | else None
174 | let (|Str16|_|) (length: int) =
175 | if length < 0xFFFF then Some(length)
176 | else None
177 | (* For now, there is no necessity to think about the string whose length is greater than 2^32-1.
178 | let (|Str32|_|) (length: int) =
179 | if length < 0xFFFFFFFF then Some(length)
180 | else None*)
181 | match length with
182 | | FixStr length -> Array.append
183 | [| byte (160 + length) |]
184 | bytes // string whose length is upto 31.
185 | | Str8 length -> Array.append
186 | [| Format.Str8
187 | byte length |]
188 | bytes // string whose length is upto 2^8-1.
189 | | Str16 length -> Array.append
190 | [| Format.Str16
191 | byte (length >>> 8)
192 | byte (length &&& 0x00FF) |]
193 | bytes // string whose length is upto 2^16-1.
194 | | _ -> Array.append
195 | [| Format.Str32
196 | byte (length >>> 24)
197 | byte ((length &&& 0x00FF0000) >>> 16)
198 | byte ((length &&& 0x0000FF00) >>> 8)
199 | byte (length &&& 0x000000FF) |]
200 | bytes // string whose length is greater than 2^16-1.
201 |
202 | []
203 | let packBin (bs: byte[]) =
204 | let length = bs.Length
205 | if length <= 255 then Array.append [| Format.Bin8; byte(length) |] bs
206 | elif length <= 65535 then Array.append
207 | [| Format.Bin16
208 | byte (length >>> 8)
209 | byte (length &&& 0x00FF) |]
210 | bs
211 | else Array.append
212 | [| Format.Bin32
213 | byte (length >>> 24)
214 | byte ((length &&& 0x00FF0000) >>> 16)
215 | byte ((length &&& 0x0000FF00) >>> 8)
216 | byte (length &&& 0x000000FF) |]
217 | bs
218 |
219 | []
220 | let packExt (t: sbyte) (bs: byte[]) =
221 | let length = bs.Length
222 | if length = 1 then Array.append [| Format.FixExt1; byte(t) |] bs
223 | elif length = 2 then Array.append [| Format.FixExt2; byte(t) |] bs
224 | elif 3 <= length && length <= 4 then Array.append [| Format.FixExt4; byte(t) |] bs
225 | elif 5 <= length && length <= 8 then Array.append [| Format.FixExt8; byte(t) |] bs
226 | elif 9 <= length && length <= 16 then Array.append [| Format.FixExt16; byte(t) |] bs
227 | elif length <= 255 then Array.append [| Format.Ext8; byte(length); byte(t) |] bs
228 | elif length <= 65535 then Array.append
229 | [| Format.Ext16
230 | byte (length >>> 8)
231 | byte (length &&& 0x00FF)
232 | byte (t) |]
233 | bs
234 | else Array.append
235 | [| Format.Ext32
236 | byte (length >>> 24)
237 | byte ((length &&& 0x00FF0000) >>> 16)
238 | byte ((length &&& 0x0000FF00) >>> 8)
239 | byte (length &&& 0x000000FF)
240 | byte (t) |]
241 | bs
242 |
243 | []
244 | let rec packOne = function
245 | | Value.Nil -> packNil()
246 | | Value.Bool b -> packBool b
247 | | Value.Float32 f -> packFloat32 f
248 | | Value.Float64 f -> packFloat f
249 | | Value.UInt8 u -> packByte u
250 | | Value.UInt16 u -> packUInt16 u
251 | | Value.UInt32 u -> packUInt32 u
252 | | Value.UInt64 u -> packUInt64 u
253 | | Value.Int8 i -> packSByte i
254 | | Value.Int16 i -> packInt16 i
255 | | Value.Int32 i -> packInt i
256 | | Value.Int64 i -> packInt64 i
257 | | Value.String s -> packString s
258 | | Value.Bin b -> packBin b
259 | | Value.Array arr ->
260 | let fmapped = Array.collect packOne arr
261 | let length = arr.Length
262 | if length <= 15 then Array.append
263 | [| byte (0b10010000 + length) |]
264 | fmapped
265 | elif length <= 65535 then Array.append
266 | [| Format.Array16
267 | byte (length >>> 8)
268 | byte (length &&& 0x00FF) |]
269 | fmapped
270 | else Array.append
271 | [| Format.Array32
272 | byte (length >>> 24)
273 | byte ((length &&& 0x00FF0000) >>> 16)
274 | byte ((length &&& 0x0000FF00) >>> 8)
275 | byte (length &&& 0x000000FF) |]
276 | fmapped
277 | | Value.Map m ->
278 | let length = m.Count
279 | let flatten = Map.toArray m |> Array.collect (fun (k, v) -> Array.append (packOne k) (packOne v))
280 | if length <= 15 then Array.append
281 | [| byte (0b10000000 + length) |]
282 | flatten
283 | elif length <= 65535 then Array.append
284 | [| Format.Map16
285 | byte (length >>> 8)
286 | byte (length &&& 0x00FF) |]
287 | flatten
288 | else Array.append
289 | [| Format.Map32
290 | byte (length >>> 24)
291 | byte ((length &&& 0x00FF0000) >>> 16)
292 | byte ((length &&& 0x0000FF00) >>> 8)
293 | byte (length &&& 0x000000FF) |]
294 | flatten
295 | | Value.Ext (i, b) -> packExt i b
296 |
297 | []
298 | let pack (values: Value []) = values |> Array.map packOne |> Array.concat
--------------------------------------------------------------------------------
/MsgPack.Test/UnpackerTest.fs:
--------------------------------------------------------------------------------
1 | namespace MsgPack.Test.Unpacker
2 |
3 | open NUnit.Framework
4 | open MsgPack
5 | open MsgPack.Test.Extensions
6 |
7 | []
8 | module WhenUsingUnpack =
9 | []
10 | let ``Should return [| Value.UInt8 0 |] with passing 0x00`` () =
11 | Unpacker.unpack [| 0x00uy |] |> assertEquivalentTo [| Value.UInt8 0uy |]
12 |
13 | []
14 | let ``Should return [| Value.UInt8 127 |] with passing 0x7F`` () =
15 | Unpacker.unpack [| 0x7Fuy |] |> assertEquivalentTo [| Value.UInt8 127uy |]
16 |
17 | []
18 | let ``Should return [| Value.Map { Value.UInt8 0: Value.Bool false .. Value.UInt8 14: Value.Bool false } |] with passing 0x8F and byte * bool array of [| (0, false); (1, true) .. (14, false) |]`` () =
19 | let bs = Array.init 15 (fun i -> if i % 2 = 0 then [| byte(i); 0xC2uy |] else [| byte(i); 0xC3uy |]) |> Array.concat
20 | let expected = List.init 15 (fun i -> ((i |> byte |> Value.UInt8), if i % 2 = 0 then Value.Bool false else Value.Bool true)) |> Map.ofList
21 | Array.append [| 0x8Fuy |] bs |> Unpacker.unpack |> assertEquivalentTo [| Value.Map(expected) |]
22 |
23 | []
24 | let ``Should return [| Value.Array [|Value.UInt8 0 ... Value.UInt8 14|] |] with passing 0x9F and byte array of [| 0 .. 14 |]`` () =
25 | let bs = Array.init 15 (fun i -> byte(i))
26 | let expected = Array.init 15 (fun i -> i |> byte |> Value.UInt8)
27 | Array.append [| 0x9Fuy |] bs |> Unpacker.unpack |> assertEquivalentTo [| Value.Array(expected) |]
28 |
29 | []
30 | let ``Should return seq [Value.String "MessagePack"] with passing 0xAB4D6573736167655061636B`` () =
31 | Unpacker.unpack [| 0xABuy; 0x4Duy; 0x65uy; 0x73uy; 0x73uy; 0x61uy; 0x67uy; 0x65uy; 0x50uy; 0x61uy; 0x63uy; 0x6Buy |]
32 | |> assertEquivalentTo [| Value.String "MessagePack" |]
33 |
34 | []
35 | let ``Should return [| Value.Nil |] with passing 0xC0`` () =
36 | Unpacker.unpack [| 0xC0uy |] |> assertEquivalentTo [| Value.Nil |]
37 |
38 | []
39 | let ``Should return [| Value.Bool false |] with passing 0xC2`` () =
40 | Unpacker.unpack [| 0xC2uy |] |> assertEquivalentTo [| Value.Bool false |]
41 |
42 | []
43 | let ``Should return [| Value.Bool true |] with passing 0xC3`` () =
44 | Unpacker.unpack [| 0xC3uy |] |> assertEquivalentTo [| Value.Bool true |]
45 |
46 | []
47 | let ``Should return [| Value.Bin (255-length of 0xFF) |] with passing 0xC4FF and 255-length of 0xFF array`` () =
48 | let bs = Array.init 255 (fun _ -> 0xFFuy)
49 | Array.append [| 0xC4uy; 0xFFuy |] bs |> Unpacker.unpack |> assertEquivalentTo [| Value.Bin bs |]
50 |
51 | []
52 | let ``Should return seq [Value.Bin (256-length of 0x20)] with passing 0xC50100 and 256-length of 0x20 array`` () =
53 | let bs = Array.init 256 (fun _ -> 0x20uy)
54 | Array.append [| 0xC5uy; 0x01uy; 0x00uy |] bs |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Bin bs])
55 |
56 | []
57 | let ``Should return seq [Value.Bin (65535-length of 0x30)] with passing 0xC5FFFF and 65535-length of 0x30 array`` () =
58 | let bs = Array.init 65535 (fun _ -> 0x30uy)
59 | Array.append [| 0xC5uy; 0xFFuy; 0xFFuy |] bs |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Bin bs])
60 |
61 | []
62 | let ``Should return seq [Value.Bin (65536-length of 0x41)] with passing 0xC600010000 and 65536-length of 0x41 array`` () =
63 | let bs = Array.init 65536 (fun _ -> 0x41uy)
64 | Array.append [| 0xC6uy; 0x00uy; 0x01uy; 0x00uy; 0x00uy |] bs |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Bin bs])
65 |
66 | []
67 | let ``Should return seq [Value.Ext (1, 255-length of 0xFF)] with passing 0xC7FF01 and 255-length of 0xFF array`` () =
68 | let bs = Array.init 255 (fun _ -> 0xFFuy)
69 | Array.append [| 0xC7uy; 0xFFuy; 0x01uy |] bs |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Ext(1y, bs)])
70 |
71 | []
72 | let ``Should return seq [Value.Ext (2, 256-length of 0x20)] with passing 0xC8010002 and 256-length of 0x20 array`` () =
73 | let bs = Array.init 256 (fun _ -> 0x20uy)
74 | Array.append [| 0xC8uy; 0x01uy; 0x00uy; 0x02uy |] bs |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Ext(2y, bs)])
75 |
76 | []
77 | let ``Should return seq [Value.Ext (3, 65535-length 0f 0x30)] with passing 0xC8FFFF03 and 65535-length of 0x30 array`` () =
78 | let bs = Array.init 65535 (fun _ -> 0x30uy)
79 | Array.append [| 0xC8uy; 0xFFuy; 0xFFuy; 0x03uy |] bs |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Ext(3y, bs)])
80 |
81 | []
82 | let ``Should return seq [Value.Ext (4, 65536-length of 0x41)] with passing 0xC90001000004 and 65536-length of 0x41 array`` () =
83 | let bs = Array.init 65536 (fun _ -> 0x41uy)
84 | Array.append [| 0xC9uy; 0x00uy; 0x01uy; 0x00uy; 0x00uy; 0x04uy |] bs |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Ext(4y, bs)])
85 |
86 | []
87 | let ``Should return seq [Value.Float32 0.15625] with passing 0xCA3E200000`` () =
88 | Unpacker.unpack [| 0XCAuy; 0x3Euy; 0x20uy; 0x00uy; 0x00uy |] |> assertEquivalentTo (seq [Value.Float32 0.15625f])
89 |
90 | []
91 | let ``Should return seq [Value.Float32 +infinity] with passing 0xCA7F800000`` () =
92 | Unpacker.unpack [| 0xCAuy; 0x7Fuy; 0x80uy; 0x00uy; 0x00uy |] |> assertEquivalentTo (seq [Value.Float32 System.Single.PositiveInfinity])
93 |
94 | []
95 | let ``Should return seq [Value.Float64 -1.000001430511474609375] with passing 0xCBBFF0000180000000`` () =
96 | Unpacker.unpack [| 0xCBuy; 0xBFuy; 0xF0uy; 0x00uy; 0x01uy; 0x80uy; 0x00uy; 0x00uy; 0x00uy |] |> assertEquivalentTo (seq [Value.Float64 (-1.000001430511474609375)])
97 |
98 | []
99 | let ``Should return seq [Value.Float64 -infinity] with passing 0xCBFFF0000000000000`` () =
100 | Unpacker.unpack [| 0xCBuy; 0xFFuy; 0xF0uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy |] |> assertEquivalentTo (seq [Value.Float64 System.Double.NegativeInfinity])
101 |
102 | []
103 | let ``Should return seq [Value.UInt8 128] with passing 0xCC80`` () =
104 | Unpacker.unpack [| 0xCCuy; 0x80uy |] |> assertEquivalentTo (seq [ Value.UInt8 128uy ])
105 |
106 | []
107 | let ``Should return seq [Value.UInt8 255] with passing 0xCCFF`` () =
108 | Unpacker.unpack [| 0xCCuy; 0xFFuy |] |> assertEquivalentTo (seq [ Value.UInt8 255uy ])
109 |
110 | []
111 | let ``Should return seq [Value.UInt16 256] with passing 0xCD0100`` () =
112 | Unpacker.unpack [| 0xCDuy; 0x01uy; 0x00uy |] |> assertEquivalentTo (seq [ Value.UInt16 256us ])
113 |
114 | []
115 | let ``Should return seq [Value.UInt16 65535] with passing 0xCDFFFF`` () =
116 | Unpacker.unpack [| 0xCDuy; 0xFFuy; 0xFFuy |] |> assertEquivalentTo (seq [ Value.UInt16 65535us ])
117 |
118 | []
119 | let ``Should return seq [Value.UInt32 65536] with passing 0xCE00010000`` () =
120 | Unpacker.unpack [| 0xCEuy; 0x00uy; 0x01uy; 0x00uy; 0x00uy |] |> assertEquivalentTo (seq [Value.UInt32 65536u ])
121 |
122 | []
123 | let ``Should return seq [Value.UInt32 4294967295] with passing 0xCEFFFFFFFF`` () =
124 | Unpacker.unpack [| 0xCEuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy |] |> assertEquivalentTo (seq [Value.UInt32 4294967295u ])
125 |
126 | []
127 | let ``Should return seq [Value.UInt64 4294967296] with passing 0xCF0000000100000000`` () =
128 | Unpacker.unpack [| 0xCFuy; 0x00uy; 0x00uy; 0x00uy; 0x01uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy |] |> assertEquivalentTo (seq [Value.UInt64 4294967296UL ])
129 |
130 | []
131 | let ``Should return seq [Value.UInt64 18446744073709551615] with passing 0xCFFFFFFFFFFFFFFFFF`` () =
132 | Unpacker.unpack [| 0xCFuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy |] |> assertEquivalentTo (seq [Value.UInt64 18446744073709551615UL ])
133 |
134 | []
135 | let ``Should return seq [Value.Int8 (-33)] with passing 0xD0DF`` () =
136 | Unpacker.unpack [| 0xD0uy; 0xDFuy |] |> assertEquivalentTo (seq [Value.Int8 (-33y)])
137 |
138 | []
139 | let ``Should return seq [Value.Int8 (-128)] with passing 0xD080`` () =
140 | Unpacker.unpack [| 0xD0uy; 0x80uy |] |> assertEquivalentTo (seq [Value.Int8 (-128y)])
141 |
142 | []
143 | let ``Should return seq [Value.Int16 (-129)] with passing 0xD1FF7F`` () =
144 | Unpacker.unpack [| 0xD1uy; 0xFFuy; 0x7Fuy |] |> assertEquivalentTo (seq [Value.Int16 (-129s)])
145 |
146 | []
147 | let ``Should return seq [Value.Int16 (-32768)] with passing 0xD18000`` () =
148 | Unpacker.unpack [| 0xD1uy; 0x80uy; 0x00uy |] |> assertEquivalentTo (seq [Value.Int16 (-32768s)])
149 |
150 | []
151 | let ``Should return seq [Value.Int32 (-32769)] with passing 0xD2FFFF7FFF`` () =
152 | Unpacker.unpack [| 0xD2uy; 0xFFuy; 0xFFuy; 0x7Fuy; 0xFFuy |] |> assertEquivalentTo (seq [Value.Int32 (-32769)])
153 |
154 | []
155 | let ``Should return seq [Value.Int32 (-2147483648)] with passing 0xD280000000`` () =
156 | Unpacker.unpack [| 0xD2uy; 0x80uy; 0x00uy; 0x00uy; 0x00uy |] |> assertEquivalentTo (seq [Value.Int32 (-2147483648)])
157 |
158 | []
159 | let ``Should return seq [Value.Int64 (-2147483649)] with passing 0xD3FFFFFFFF7FFFFFFF`` () =
160 | Unpacker.unpack [| 0xD3uy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy; 0x7Fuy; 0xFFuy; 0xFFuy; 0xFFuy |] |> assertEquivalentTo (seq [Value.Int64 (-2147483649L)])
161 |
162 | []
163 | let ``Should return seq [Value.Int64 (-9223372036854775808)] with passing 0xD38000000000000000`` () =
164 | Unpacker.unpack [| 0xD3uy; 0x80uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy |] |> assertEquivalentTo (seq [Value.Int64 (-9223372036854775808L)])
165 |
166 | []
167 | let ``Should return seq [Value.Ext (5, [| 0xFF |])] with passing 0xD405FF`` () =
168 | [| 0xD4uy; 0x05uy; 0xFFuy |] |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Ext (5y, [| 0xFFuy |])])
169 |
170 | []
171 | let ``Should return seq [Value.Ext (6, [| 0x20; 0x30 |])] with passing 0xD5062030`` () =
172 | [| 0xD5uy; 0x06uy; 0x20uy; 0x30uy |] |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Ext (6y, [| 0x20uy; 0x30uy |])])
173 |
174 | []
175 | let ``Should return seq [Value.Ext (7, [| 0xFF; 0x20; 0x30; 0x41 |])] with passing 0xD607FF203041`` () =
176 | [| 0xD6uy; 0x07uy; 0xFFuy; 0x20uy; 0x30uy; 0x41uy |] |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Ext (7y, [| 0xFFuy; 0x20uy; 0x30uy; 0x41uy |])])
177 |
178 | []
179 | let ``Should return seq [Value.Ext (8, [| 0x20; 0x30; 0x41; 0xFF; 0x20; 0x30; 0x41; 0xFF |])] with passing 0xD708203041FF203041FF`` () =
180 | [| 0xD7uy; 0x08uy; 0x20uy; 0x30uy; 0x41uy; 0xFFuy; 0x20uy; 0x30uy; 0x41uy; 0xFFuy |] |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Ext (8y, [| 0x20uy; 0x30uy; 0x41uy; 0xFFuy; 0x20uy; 0x30uy; 0x41uy; 0xFFuy |])])
181 |
182 | []
183 | let ``Should return seq [Value.Ext (9, [| 0x20; 0x20; 0x20; 0x20; 0x30; 0x41; 0x30; 0x41; 0x30; 0x41; 0x30; 0x41; 0xFF; 0xFF; 0xFF; 0xFF |])] with passing 0xD809202020203041304130413041FFFFFFFF`` () =
184 | let bs = [| 0xD8uy; 0x09uy; 0x20uy; 0x20uy; 0x20uy; 0x20uy; 0x30uy; 0x41uy; 0x30uy; 0x41uy; 0x30uy; 0x41uy; 0x30uy; 0x41uy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy |]
185 | Unpacker.unpack bs |> assertEquivalentTo (seq [Value.Ext (9y, bs.[2..])])
186 |
187 | []
188 | let ``Should return seq [Value.String (32-length of "A")] with passing 0xD920 and 32-length of 0x41 array`` () =
189 | Array.append [| 0xD9uy; 0x20uy |] (Array.init 32 (fun _ -> 0x41uy)) |> Unpacker.unpack |> assertEquivalentTo (seq [Value.String (System.String('A', 32))])
190 |
191 | []
192 | let ``Should return seq [Value.String (255-length of "a")] with passing 0xD9FF and 255-length of 0x61 array`` () =
193 | Array.append [| 0xD9uy; 0xFFuy |] (Array.init 255 (fun _ -> 0x61uy)) |> Unpacker.unpack |> assertEquivalentTo (seq [Value.String (System.String('a', 255))])
194 |
195 | []
196 | let ``Should return seq [Value.String (256-length of "0")] with passing 0xDA0100 and 256-length of 0x30 array`` () =
197 | Array.append [| 0xDAuy; 0x01uy; 0x00uy |] (Array.init 256 (fun _ -> 0x30uy)) |> Unpacker.unpack |> assertEquivalentTo (seq [Value.String (System.String('0', 256))])
198 |
199 | []
200 | let ``Should return seq [Value.String (65535-length of "9")] with passing 0xDAFFFF and 65535-length of 0x39 array`` () =
201 | Array.append [| 0xDAuy; 0xFFuy; 0xFFuy |] (Array.init 65535 (fun _ -> 0x39uy)) |> Unpacker.unpack |> assertEquivalentTo (seq [Value.String (System.String('9', 65535))])
202 |
203 | []
204 | let ``Should return seq [Value.String (65536-length of " ")] with passing 0xDB00010000 and 65536-length of 0x20 array`` () =
205 | Array.append [| 0xDBuy; 0x00uy; 0x01uy; 0x00uy; 0x00uy |] (Array.init 65536 (fun _ -> 0x20uy)) |> Unpacker.unpack |> assertEquivalentTo (seq [Value.String (System.String(' ', 65536))])
206 |
207 | []
208 | let ``Should return seq [Value.Array (16-length of Value.Nil)] with passing 0xDC0010 and 16-length of 0xC0 array`` () =
209 | let bs = Array.init 16 (fun _ -> 0xC0uy)
210 | let expected = Array.init 16 (fun _ -> Value.Nil)
211 | Array.append [| 0xDCuy; 0x00uy; 0x10uy |] bs |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Array(expected)])
212 |
213 | []
214 | let ``Should return seq [Value.Array (65535-length of Value.Bool false)] with passing 0xDCFFFF and 65535-length of 0xC2 array`` () =
215 | let bs = Array.init 65535 (fun _ -> 0xC2uy)
216 | let expected = Array.init 65535 (fun _ -> Value.Bool false)
217 | Array.append [| 0xDCuy; 0xFFuy; 0xFFuy |] bs |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Array(expected)])
218 |
219 | []
220 | let ``Should return seq [Value.Array (65536-length of Value.Bool true)] with passing 0xDD00010000 and 65536-length of 0xC3 array`` () =
221 | let bs = Array.init 65536 (fun _ -> 0xC3uy)
222 | let expected = Array.init 65536 (fun _ -> Value.Bool true)
223 | Array.append [| 0xDDuy; 0x00uy; 0x01uy; 0x00uy; 0x00uy |] bs |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Array(expected)])
224 |
225 | []
226 | let ``Should return seq [Value.Map (16-length of (int format family, bool format family))] with passing 0xDE0010 and 16-length of key value collections`` () =
227 | let bs = Array.init 16 (fun i -> if i % 2 = 0 then [| byte(i); 0xC2uy |] else [| byte(i); 0xC3uy |]) |> Array.concat
228 | let expected = List.init 16 (fun i -> (i |> byte |> Value.UInt8), if i % 2 = 0 then Value.Bool false else Value.Bool true) |> Map.ofList
229 | Array.append [| 0xDEuy; 0x00uy; 0x10uy |] bs |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Map(expected)])
230 |
231 | []
232 | let ``Should return seq [Value.Map (65535-length of (int format family, bool format family))] with passing 0xDEFFFF and 65535-length of key value collections`` () =
233 | let bs = Array.init 65535 (fun i -> Array.append (Packer.packInt i) [| (if i % 2 = 0 then 0xC2uy else 0xC3uy) |]) |> Array.concat
234 | let expected =
235 | List.init 65535
236 | (fun i ->
237 | if i <= 255 then
238 | i |> byte |> Value.UInt8
239 | else
240 | i |> uint16 |> Value.UInt16
241 | , if i % 2 = 0 then Value.Bool false else Value.Bool true)
242 | |> Map.ofList
243 | Array.append [| 0xDEuy; 0xFFuy; 0xFFuy |] bs |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Map(expected)])
244 |
245 | []
246 | let ``Should return seq [Value.Map (65536-length of (int format family, bool format family))] with passing 0xDF00010000 and 65536-length of key value collections`` () =
247 | let bs = Array.init 65536 (fun i -> Array.append (Packer.packInt i) [| 0xC3uy |]) |> Array.concat
248 | let expected =
249 | List.init 65536
250 | (fun i ->
251 | if i <= 255 then
252 | i |> byte |> Value.UInt8
253 | elif i<= 65535 then
254 | i |> uint16 |> Value.UInt16
255 | else
256 | i |> uint32 |> Value.UInt32
257 | , Value.Bool true)
258 | |> Map.ofList
259 | Array.append [| 0xDFuy; 0x00uy; 0x01uy; 0x00uy; 0x00uy |] bs |> Unpacker.unpack |> assertEquivalentTo (seq [Value.Map(expected)])
260 |
261 | []
262 | let ``Should return seq [Value.Int8 (-1)] with passing 0xFF`` () =
263 | Unpacker.unpack [| 0xFFuy |] |> assertEquivalentTo (seq [Value.Int8 (-1y)])
264 |
265 | []
266 | let ``Should return seq [Value.Int8 (-32)] with passing 0xE0`` () =
267 | Unpacker.unpack [| 0xE0uy |] |> assertEquivalentTo (seq [Value.Int8 (-32y)])
--------------------------------------------------------------------------------
/MsgPack.Test/PackerTest.fs:
--------------------------------------------------------------------------------
1 | namespace MsgPack.Test.Packer
2 |
3 | open NUnit.Framework
4 | open MsgPack
5 |
6 | open MsgPack.Test.Extensions
7 |
8 | []
9 | module WhenUsingPackBool =
10 | []
11 | let ``Should return 0xC3 with passing true``() =
12 | true |> Packer.packBool |> assertEquivalentTo [| 0xC3uy |]
13 |
14 | []
15 | let ``Should return 0xC2 with passing false``() =
16 | false |> Packer.packBool |> assertEquivalentTo [| 0xC2uy |]
17 |
18 | []
19 | module WhenUsingPackByte =
20 | []
21 | let ``Should return 0x7F with passing 127``() =
22 | 127uy |> Packer.packByte |> assertEquivalentTo [| 0x7Fuy |]
23 |
24 | []
25 | let ``Should return 0xCC80 with passing 128``() =
26 | 128uy |> Packer.packByte |> assertEquivalentTo [| 0xCCuy; 0x80uy |]
27 |
28 | []
29 | let ``Should return 0xCDFF with passing 255``() =
30 | 255uy |> Packer.packByte |> assertEquivalentTo [| 0xCCuy; 0xFFuy |]
31 |
32 | []
33 | module WhenUsingPackUInt16 =
34 | []
35 | let ``Should return 0x7F with passing 127``() =
36 | 127us |> Packer.packUInt16 |> assertEquivalentTo [| 0x7Fuy |]
37 |
38 | []
39 | let ``Should return 0xCC80 with passing 128``() =
40 | 128us |> Packer.packUInt16 |> assertEquivalentTo [| 0xCCuy; 0x80uy |]
41 |
42 | []
43 | let ``Should return 0xCCFF with passing 255``() =
44 | 255us |> Packer.packUInt16 |> assertEquivalentTo [| 0xCCuy; 0xFFuy |]
45 |
46 | []
47 | let ``Should return 0xCD0100 with passing 256``() =
48 | 256us |> Packer.packUInt16 |> assertEquivalentTo [| 0xCDuy; 0x01uy; 0x00uy |]
49 |
50 | []
51 | let ``Should return 0xCDFFFF with passing 65535``() =
52 | 65535us |> Packer.packUInt16 |> assertEquivalentTo [| 0xCDuy; 0xFFuy; 0xFFuy |]
53 |
54 | []
55 | module WhenUsingPackUInt32 =
56 | []
57 | let ``Should return 0x7F with passing 127``() =
58 | 127u |> Packer.packUInt32 |> assertEquivalentTo [| 0x7Fuy |]
59 |
60 | []
61 | let ``Should return 0xCC80 with passing 128``() =
62 | 128u |> Packer.packUInt32 |> assertEquivalentTo [| 0xCCuy; 0x80uy |]
63 |
64 | []
65 | let ``Should return 0xCCFF with passing 255``() =
66 | 255u |> Packer.packUInt32 |> assertEquivalentTo [| 0xCCuy; 0xFFuy |]
67 |
68 | []
69 | let ``Should return 0xCD0100 with passing 256``() =
70 | 256u |> Packer.packUInt32 |> assertEquivalentTo [| 0xCDuy; 0x01uy; 0x00uy |]
71 |
72 | []
73 | let ``Should return 0xCDFFFF with passing 65535``() =
74 | 65535u |> Packer.packUInt32 |> assertEquivalentTo [| 0xCDuy; 0xFFuy; 0xFFuy |]
75 |
76 | []
77 | let ``Should return 0xCE00010000 with passing 65536``() =
78 | 65536u |> Packer.packUInt32 |> assertEquivalentTo [| 0xCEuy; 0x00uy; 0x01uy; 0x00uy; 0x00uy |]
79 |
80 | []
81 | let ``Should return 0xCEFFFFFFFF with passing 4294967295``() =
82 | 4294967295u |> Packer.packUInt32 |> assertEquivalentTo [| 0xCEuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy |]
83 |
84 | []
85 | let ``Should return 0xCE12345678 with passing 0x12345678``() =
86 | 0x12345678u |> Packer.packUInt32 |> assertEquivalentTo [| 0xCEuy; 0x12uy; 0x34uy; 0x56uy; 0x78uy |]
87 |
88 | []
89 | module WhenUsingPackUInt64 =
90 | []
91 | let ``Should return 0xCC80 with passing 128``() =
92 | 128UL |> Packer.packUInt64 |> assertEquivalentTo [| 0xCCuy; 0x80uy |]
93 |
94 | []
95 | let ``Should return 0xCCFF with passing 255``() =
96 | 255UL |> Packer.packUInt64 |> assertEquivalentTo [| 0xCCuy; 0xFFuy |]
97 |
98 | []
99 | let ``Should return 0xCD0100 with passing 256``() =
100 | 256UL |> Packer.packUInt64 |> assertEquivalentTo [| 0xCDuy; 0x01uy; 0x00uy |]
101 |
102 | []
103 | let ``Should return 0xCDFFFF with passing 65535``() =
104 | 65535UL |> Packer.packUInt64 |> assertEquivalentTo [| 0xCDuy; 0xFFuy; 0xFFuy |]
105 |
106 | []
107 | let ``Should return 0xCE010000 with passing 65536``() =
108 | 65536UL |> Packer.packUInt64 |> assertEquivalentTo [| 0xCEuy; 0x00uy; 0x01uy; 0x00uy; 0x00uy |]
109 |
110 | []
111 | let ``Should return 0xCEFFFFFFFF with passing 4294967295``() =
112 | 4294967295UL |> Packer.packUInt64 |> assertEquivalentTo [| 0xCEuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy |]
113 |
114 | []
115 | let ``Should return 0xCF0000000100000000 with passing 4294967296``() =
116 | 4294967296UL |> Packer.packUInt64 |> assertEquivalentTo [| 0xCFuy; 0x00uy; 0x00uy; 0x00uy; 0x01uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy |]
117 |
118 | []
119 | let ``Should return 0xCFFFFFFFFFFFFFFFFF with passing 18446744073709551615``() =
120 | 18446744073709551615UL |> Packer.packUInt64 |> assertEquivalentTo [| 0xCFuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy |]
121 |
122 | []
123 | let ``Should return 0xCE0123456789ABCDEF with passing 0x0123456789ABCDEF``() =
124 | 0x0123456789ABCDEFUL |> Packer.packUInt64 |> assertEquivalentTo [| 0xCFuy; 0x01uy; 0x23uy; 0x45uy; 0x67uy; 0x89uy; 0xABuy; 0xCDuy; 0xEFuy |]
125 |
126 | []
127 | module WhenUsingPackSByte =
128 | []
129 | let ``Should return 0x7F with passing 127`` () =
130 | 127y |> Packer.packSByte |> assertEquivalentTo [| 0x7Fuy |]
131 |
132 | []
133 | let ``Should return 0xE0 with passing -32`` () =
134 | -32y |> Packer.packSByte |> assertEquivalentTo [| 0xE0uy |]
135 |
136 | []
137 | let ``Should return 0xD0DF with passing -33`` () =
138 | -33y |> Packer.packSByte |> assertEquivalentTo [| 0xD0uy; 0xDFuy |]
139 |
140 | []
141 | let ``Should return 0xD080 with passing -128`` () =
142 | -128y |> Packer.packSByte |> assertEquivalentTo [| 0xD0uy; 0x80uy |]
143 |
144 | []
145 | module WhenUsingPackInt16 =
146 | []
147 | let ``Should return 0xCD7FFF with passing 32767`` () =
148 | 32767s |> Packer.packInt16 |> assertEquivalentTo [| 0xCDuy; 0x7Fuy; 0xFFuy |]
149 |
150 | []
151 | let ``Should return 0xCD0100 with passing 256`` () =
152 | 256s |> Packer.packInt16 |> assertEquivalentTo [| 0xCDuy; 0x01uy; 0x00uy |]
153 |
154 | []
155 | let ``Should return 0xCCFF with passing 255`` () =
156 | 255s |> Packer.packInt16 |> assertEquivalentTo [| 0xCCuy; 0xFFuy |]
157 |
158 | []
159 | let ``Should return 0xCC80 with passing 128`` () =
160 | 128s |> Packer.packInt16 |> assertEquivalentTo [| 0xCCuy; 0x80uy |]
161 |
162 | []
163 | let ``Should return 0x7F with passing 127`` () =
164 | 127s |> Packer.packInt16 |> assertEquivalentTo [| 0x7Fuy |]
165 |
166 | []
167 | let ``Should return 0xE0 with passing -32`` () =
168 | -32s |> Packer.packInt16 |> assertEquivalentTo [| 0xE0uy |]
169 |
170 | []
171 | let ``Should return 0xD0DF with passing -33`` () =
172 | -33s |> Packer.packInt16 |> assertEquivalentTo [| 0xD0uy; 0xDFuy |]
173 |
174 | []
175 | let ``Should return 0xD080 with passing -128`` () =
176 | -128s |> Packer.packInt16 |> assertEquivalentTo [| 0xD0uy; 0x80uy |]
177 |
178 | []
179 | let ``Should return 0xD1FF7F with passing -129`` () =
180 | -129s |> Packer.packInt16 |> assertEquivalentTo [| 0xD1uy; 0xFFuy; 0x7Fuy |]
181 |
182 | []
183 | let ``Should return 0xD18000 with passing -32768`` () =
184 | -32768s |> Packer.packInt16 |> assertEquivalentTo [| 0xD1uy; 0x80uy; 0x00uy |]
185 |
186 | []
187 | module WhenUsingPackInt =
188 | []
189 | let ``Should return 0xCE7FFFFFFF with passing 2147483647``() =
190 | 2147483647 |> Packer.packInt |> assertEquivalentTo [| 0xCEuy; 0x7Fuy; 0xFFuy; 0xFFuy; 0xFFuy |]
191 |
192 | []
193 | let ``Should return 0xCE00010000 with passing 65536``() =
194 | 65536 |> Packer.packInt |> assertEquivalentTo [| 0xCEuy; 0x00uy; 0x01uy; 0x00uy; 0x00uy |]
195 |
196 | []
197 | let ``Should return 0xCDFFFF with passing 65535``() =
198 | 65535 |> Packer.packInt |> assertEquivalentTo [| 0xCDuy; 0xFFuy; 0xFFuy |]
199 |
200 | []
201 | let ``Should return 0xCD0100 with passing 256``() =
202 | 256 |> Packer.packInt |> assertEquivalentTo [| 0xCDuy; 0x01uy; 0x00uy |]
203 |
204 | []
205 | let ``Should return 0xCCFF with passing 255``() =
206 | 255 |> Packer.packInt |> assertEquivalentTo [| 0xCCuy; 0xFFuy |]
207 |
208 | []
209 | let ``Should return 0xCC80 with passing 128``() =
210 | 128 |> Packer.packInt |> assertEquivalentTo [| 0xCCuy; 0x80uy |]
211 |
212 | []
213 | let ``Should return 0x7F with passing 127``() =
214 | 127 |> Packer.packInt |> assertEquivalentTo [| 0x7Fuy |]
215 |
216 | []
217 | let ``Should return 0xE0 with passing -32``() =
218 | -32 |> Packer.packInt |> assertEquivalentTo [| 0xE0uy |]
219 |
220 | []
221 | let ``Should return 0xD0DF with passing -33``() =
222 | -33 |> Packer.packInt |> assertEquivalentTo [| 0xD0uy; 0xDFuy |]
223 |
224 | []
225 | let ``Should return 0xD080 with passing -128``() =
226 | -128 |> Packer.packInt |> assertEquivalentTo [| 0xD0uy; 0x80uy |]
227 |
228 | []
229 | let ``Should return 0xD1FF7F with passing -129``() =
230 | -129 |> Packer.packInt |> assertEquivalentTo [| 0xD1uy; 0xFFuy; 0x7Fuy |]
231 |
232 | []
233 | let ``Should return 0xD18000 with passing -32768``() =
234 | -32768 |> Packer.packInt |> assertEquivalentTo [| 0xD1uy; 0x80uy; 0x00uy |]
235 |
236 | []
237 | let ``Should return 0xD2FFFF7FFF with passing -32769``() =
238 | -32769 |> Packer.packInt |> assertEquivalentTo [| 0xD2uy; 0xFFuy; 0xFFuy; 0x7Fuy; 0xFFuy |]
239 |
240 | []
241 | let ``Should return 0xD280000000 with passing -2147483648``() =
242 | -2147483648 |> Packer.packInt |> assertEquivalentTo [| 0xD2uy; 0x80uy; 0x00uy; 0x00uy; 0x00uy |]
243 |
244 | []
245 | module WhenUsingPackInt64 =
246 | []
247 | let ``Should return 0xCF7FFFFFFFFFFFFFFF with passing 9223372036854775807``() =
248 | 9223372036854775807L |> Packer.packInt64 |> assertEquivalentTo [| 0xCFuy; 0x7Fuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy |]
249 |
250 | []
251 | let ``Should return 0xCF0000000100000000 with passing 4294967296``() =
252 | 4294967296L |> Packer.packInt64 |> assertEquivalentTo [| 0xCFuy; 0x00uy; 0x00uy; 0x00uy; 0x01uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy |]
253 |
254 | []
255 | let ``Should return 0xCE7FFFFFFF with passing 4294967295``() =
256 | 4294967295L |> Packer.packInt64 |> assertEquivalentTo [| 0xCEuy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy |]
257 |
258 | []
259 | let ``Should return 0xCE00010000 with passing 65536``() =
260 | 65536L |> Packer.packInt64 |> assertEquivalentTo [| 0xCEuy; 0x00uy; 0x01uy; 0x00uy; 0x00uy |]
261 |
262 | []
263 | let ``Should return 0xCDFFFF with passing 65535``() =
264 | 65535L |> Packer.packInt64 |> assertEquivalentTo [| 0xCDuy; 0xFFuy; 0xFFuy |]
265 |
266 | []
267 | let ``Should return 0xCD0100 with passing 256``() =
268 | 256L |> Packer.packInt64 |> assertEquivalentTo [| 0xCDuy; 0x01uy; 0x00uy |]
269 |
270 | []
271 | let ``Should return 0xCCFF with passing 255``() =
272 | 255L |> Packer.packInt64 |> assertEquivalentTo [| 0xCCuy; 0xFFuy |]
273 |
274 | []
275 | let ``Should return 0xCC80 with passing 128``() =
276 | 128L |> Packer.packInt64 |> assertEquivalentTo [| 0xCCuy; 0x80uy |]
277 |
278 | []
279 | let ``Should return 0x7F with passing 127``() =
280 | 127L |> Packer.packInt64 |> assertEquivalentTo [| 0x7Fuy |]
281 |
282 | []
283 | let ``Should return 0xE0 with passing -32``() =
284 | -32L |> Packer.packInt64 |> assertEquivalentTo [| 0xE0uy |]
285 |
286 | []
287 | let ``Should return 0xD0DF with passing -33``() =
288 | -33L |> Packer.packInt64 |> assertEquivalentTo [| 0xD0uy; 0xDFuy |]
289 |
290 | []
291 | let ``Should return 0xD080 with passing -128``() =
292 | -128L |> Packer.packInt64 |> assertEquivalentTo [| 0xD0uy; 0x80uy |]
293 |
294 | []
295 | let ``Should return 0xD1FF7F with passing -129``() =
296 | -129L |> Packer.packInt64 |> assertEquivalentTo [| 0xD1uy; 0xFFuy; 0x7Fuy |]
297 |
298 | []
299 | let ``Should return 0xD18000 with passing -32768``() =
300 | -32768L |> Packer.packInt64 |> assertEquivalentTo [| 0xD1uy; 0x80uy; 0x00uy |]
301 |
302 | []
303 | let ``Should return 0xD2FFFF7FFF with passing -32769``() =
304 | -32769L |> Packer.packInt64 |> assertEquivalentTo [| 0xD2uy; 0xFFuy; 0xFFuy; 0x7Fuy; 0xFFuy |]
305 |
306 | []
307 | let ``Should return 0xD280000000 with passing -2147483648``() =
308 | -2147483648L |> Packer.packInt64 |> assertEquivalentTo [| 0xD2uy; 0x80uy; 0x00uy; 0x00uy; 0x00uy |]
309 |
310 | []
311 | let ``Should return 0xD3FFFFFFFF7FFFFFFF with passing -2147483649``() =
312 | -2147483649L |> Packer.packInt64 |> assertEquivalentTo [| 0xD3uy; 0xFFuy; 0xFFuy; 0xFFuy; 0xFFuy; 0x7Fuy; 0xFFuy; 0xFFuy; 0xFFuy |]
313 |
314 | []
315 | let ``Should return 0xD38000000000000000 with passing -9223372036854775808``() =
316 | -9223372036854775808L |> Packer.packInt64 |> assertEquivalentTo [| 0xD3uy; 0x80uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy |]
317 |
318 | []
319 | module WhenUsingPackFloat32 =
320 | []
321 | let ``Should return 0xCA00000000 with passing 0.0`` () =
322 | 0.0f |> Packer.packFloat32 |> assertEquivalentTo [| 0xCAuy; 0x00uy; 0x00uy; 0x00uy; 0x00uy |]
323 |
324 | []
325 | let ``Should reutnr 0xCA3F808000 with passing 1.00390625`` () =
326 | 1.00390625f |> Packer.packFloat32 |> assertEquivalentTo [| 0xCAuy; 0x3Fuy; 0x80uy; 0x80uy; 0x00uy |]
327 |
328 | []
329 | let ``Should return 0xCABF800080 with passing -1.0000152587890625`` () =
330 | -1.0000152587890625f |> Packer.packFloat32 |> assertEquivalentTo [| 0xCAuy; 0xBFuy; 0x80uy; 0x00uy; 0x80uy |]
331 |
332 | []
333 | let ``Should return 0xCA7F800000 with passing +infinity`` () =
334 | System.Single.PositiveInfinity |> Packer.packFloat32 |> assertEquivalentTo [| 0xCAuy; 0x7Fuy; 0x80uy; 0x00uy; 0x00uy |]
335 |
336 | []
337 | let ``Should return 0xCAFF800000 with passing -infinity`` () =
338 | System.Single.NegativeInfinity |> Packer.packFloat32 |> assertEquivalentTo [| 0xCAuy; 0xFFuy; 0x80uy; 0x00uy; 0x00uy |]
339 |
340 | []
341 | module WhenUsingPackFloat =
342 | []
343 | let ``Should return 0xCB0000000000000000 with passing 0.0`` () =
344 | 0.0 |> Packer.packFloat |> assertEquivalentTo [| 0xCBuy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy |]
345 |
346 | []
347 | let ``Should return 0xCB3FF0800000000000 with passing 1.03125`` () =
348 | 1.03125 |> Packer.packFloat |> assertEquivalentTo [| 0xCBuy; 0x3Fuy; 0xF0uy; 0x80uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy |]
349 |
350 | []
351 | let ``Should return 0xCBBFF0000180000000 with passing -1.000001430511474609375`` () =
352 | -1.000001430511474609375 |> Packer.packFloat |> assertEquivalentTo [| 0xCBuy; 0xBFuy; 0xF0uy; 0x00uy; 0x01uy; 0x80uy; 0x00uy; 0x00uy; 0x00uy |]
353 |
354 | []
355 | let ``Should return 0xCB3FF0000000010880 with passing 1.000000000015035084288683719933`` () =
356 | 1.000000000015035084288683719933 |> Packer.packFloat |> assertEquivalentTo [| 0xCBuy; 0x3Fuy; 0xF0uy; 0x00uy; 0x00uy; 0x00uy; 0x01uy; 0x08uy; 0x80uy |]
357 |
358 | []
359 | let ``Should return 0xCB7FF0000000000000 with passing +infinity`` () =
360 | System.Double.PositiveInfinity |> Packer.packFloat |> assertEquivalentTo [| 0xCBuy; 0x7Fuy; 0xF0uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy |]
361 |
362 | []
363 | let ``Should return 0xCBFFF0000000000000 with passing -infinity`` () =
364 | System.Double.NegativeInfinity |> Packer.packFloat |> assertEquivalentTo [| 0xCBuy; 0xFFuy; 0xF0uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy; 0x00uy |]
365 |
366 | []
367 | module WhenUsingPackNil =
368 | []
369 | let ``Should return 0xC0`` () =
370 | Packer.packNil() |> assertEquivalentTo [| 0xC0uy |]
371 |
372 | []
373 | module WhenUsingPackString =
374 | []
375 | let ``Should return 0xA7636F6D70616374 with passing "compact"`` () =
376 | "compact" |> Packer.packString |> assertEquivalentTo [| 0xA7uy; 0x63uy; 0x6Fuy; 0x6Duy; 0x70uy; 0x61uy; 0x63uy; 0x74uy |]
377 |
378 | []
379 | let ``Should return byte[] and its format header is 0xD9 and its length is 45 with passing "The quick brown fox jumps over the lazy dog"(the length is 43)`` () =
380 | let sut = "The quick brown fox jumps over the lazy dog" |> Packer.packString
381 | sut.Length |> assertEqualTo 45
382 | sut.[0..1] |> assertEquivalentTo [| 0xD9uy; 0x2Buy |]
383 |
384 | []
385 | let ``Should return byte[] and its format header is 0xDA and its length is 261 with passing 258-length string`` () =
386 | let sut = System.String('a', 258) |> Packer.packString
387 | sut.Length |> assertEqualTo 261
388 | sut.[0..2] |> assertEquivalentTo [| 0xDAuy; 0x01uy; 0x02uy |]
389 |
390 | []
391 | let ``Should return byte[] and its format header is 0xDB and its length is 16909065 with passing 16909060-length string`` () =
392 | let sut = System.String('a', 16909060) |> Packer.packString
393 | sut.Length |> assertEqualTo 16909065
394 | sut.[0..4] |> assertEquivalentTo [| 0xDBuy; 0x01uy; 0x02uy; 0x03uy; 0x04uy |]
395 |
396 | []
397 | module WhenUsingPackBin =
398 | []
399 | let ``Should return byte[] and its format header is 0xC4 and its length is 257 with passing [| 0 .. 254 |]`` () =
400 | let sut = [| 0uy .. 254uy |] |> Packer.packBin
401 | sut.Length |> assertEqualTo 257
402 | sut.[0..1] |> assertEquivalentTo [| 0xC4uy; 0xFFuy |]
403 |
404 | []
405 | let ``Should return byte[] and its format header is 0xC5 and its length is 259 with passing [| 0 .. 255 |]`` () =
406 | let sut = [| 0uy .. 255uy |] |> Packer.packBin
407 | sut.Length |> assertEqualTo 259
408 | sut.[0..2] |> assertEquivalentTo [| 0xC5uy; 0x01uy; 0x00uy |]
409 |
410 | []
411 | let ``Should return byte[] and its format header is 0xC5 and its length is 65538 with passing 65535-length bin array`` () =
412 | let sut = Array.create 65535 0uy |> Packer.packBin
413 | sut.Length |> assertEqualTo 65538
414 | sut.[0..2] |> assertEquivalentTo [| 0xC5uy; 0xFFuy; 0xFFuy |]
415 |
416 | []
417 | let ``Should return byte[] and its format header is 0xC6 and its length is 65541 with passing 65536-length bin array`` () =
418 | let sut = Array.create 65536 0uy |> Packer.packBin
419 | sut.Length |> assertEqualTo 65541
420 | sut.[0..4] |> assertEquivalentTo [| 0xC6uy; 0x00uy; 0x01uy; 0x00uy; 0x00uy |]
421 |
422 | []
423 | module WhenUsingPackArray =
424 | []
425 | let ``Should return 0x9400010203 with passing UInt8 array of [| 0 1 2 3 |]`` () =
426 | let sut = Value.Array [| Value.UInt8(0uy); Value.UInt8(1uy); Value.UInt8(2uy); Value.UInt8(3uy) |] |> Packer.packOne
427 | sut |> assertEquivalentTo [| 0x94uy; 0x00uy; 0x01uy; 0x02uy; 0x03uy |]
428 |
429 | []
430 | let ``Should return byte[] and its format header is 0xDC and its length is 19 with passing 16-length Bool array of [| true .. true |]`` () =
431 | let sut = Array.create 16 (Value.Bool true) |> fun arr -> Value.Array arr |> Packer.packOne
432 | sut.Length |> assertEqualTo 19
433 | sut.[0..2] |> assertEquivalentTo [| 0xDCuy; 0x00uy; 0x10uy |]
434 | sut.[3..(sut.Length-1)] |> assertEquivalentTo (Array.create 16 0xC3uy)
435 |
436 | []
437 | let ``Should return byte[] and its format header is 0xDD and its length is 131077 with passing 65536-length String array of [| 'a' .. 'a' |]`` () =
438 | let sut = Array.create 65536 (Value.String "a") |> fun arr -> Value.Array arr |> Packer.packOne
439 | sut.Length |> assertEqualTo 131077
440 | sut.[0..4] |> assertEquivalentTo [| 0xDDuy; 0x00uy; 0x01uy; 0x00uy; 0x00uy |]
441 | //sut.[5..(sut.Length-1)] |> assertEquivalentTo ((Array.create 65536 [| 0xA1uy; 0x61uy |]) |> Array.collect id)
442 |
443 | []
444 | module WhenUsingPackMap =
445 | []
446 | let ``Should return 0x82A7636F6D70616374C3A6736368656D6100 with passing {"compact": true, "schema": 0}`` () =
447 | let sut = Value.Map (Map.ofList [(Value.String("compact"), Value.Bool(true)); (Value.String("schema"), Value.UInt8(0uy))]) |> Packer.packOne
448 | sut |> assertEquivalentTo [| 0x82uy; 0xA7uy; 0x63uy; 0x6Fuy; 0x6Duy; 0x70uy; 0x61uy; 0x63uy; 0x74uy; 0xC3uy; 0xA6uy; 0x73uy; 0x63uy; 0x68uy; 0x65uy; 0x6Duy; 0x61uy; 0x00uy |]
449 |
450 | []
451 | let ``Should return byte[] and its format header is 0x8F and its length is 46 with passing 15-length key-value pairs of {1: '1', ..., 15: 'F'}`` () =
452 | let sut = [| for i in 1uy .. 15uy -> (Value.UInt8(i), Value.String(i.ToString("X"))) |] |> Map.ofArray |> Value.Map |> Packer.packOne
453 | sut.Length |> assertEqualTo 46
454 | sut.[0] |> assertEqualTo 0x8Fuy
455 |
456 | []
457 | let ``Should return byte[] and its format header is 0xDE and its length is 35 with passing 16-length key-value pairs of {1: true, ..., 16: false}`` () =
458 | let sut = [| for i in 1uy .. 16uy -> (Value.UInt8(i), Value.Bool(i % 2uy = 0uy)) |] |> Map.ofArray |> Value.Map |> Packer.packOne
459 | sut.Length |> assertEqualTo 35
460 | sut.[0..2] |> assertEquivalentTo [| 0xDEuy; 0x00uy; 0x10uy |]
461 |
462 | []
463 | let ``Should return byte[] and its format header is 0xDE and its length is 261761 with passing 65535-length key-value pairs of {1: true, ..., 65535: true}`` () =
464 | let sut = [ for i in 1us .. 65535us -> (Value.UInt16(i), Value.Bool(i % 2us = 0us)) ] |> Map.ofList |> Value.Map |> Packer.packOne
465 | sut.Length |> assertEqualTo 261761
466 | sut.[0..2] |> assertEquivalentTo [| 0xDEuy; 0xFFuy; 0xFFuy |]
467 |
468 | []
469 | let ``Should return byte[] and its format header is 0xDF and its length 261769 with passing 65536-length key-value pairs of {1: true, ..., 65536: false}`` () =
470 | let sut = [ for i in 1u .. 65536u -> (Value.UInt32(i), Value.Bool(i % 2u = 0u)) ] |> Map.ofList |> Value.Map |> Packer.packOne
471 | sut.Length |> assertEqualTo 261769
472 | sut.[0..4] |> assertEquivalentTo [| 0xDFuy; 0x00uy; 0x01uy; 0x00uy; 0x00uy |]
473 |
474 | []
475 | module WhenUsingPackExt =
476 | []
477 | let ``Should return 0xD40100 with passing (1, [| 0 |])`` () =
478 | (1y, [| 0uy |]) ||> Packer.packExt |> assertEquivalentTo [| 0xD4uy; 0x01uy; 0x00uy |]
479 |
480 | []
481 | let ``Should return 0xD5020001 with passing (2, [| 0; 1 |])`` () =
482 | (2y, [| 0uy; 1uy |]) ||> Packer.packExt |> assertEquivalentTo [| 0xD5uy; 0x02uy; 0x00uy; 0x01uy |]
483 |
484 | []
485 | let ``Should return 0xD603000102 with passing (3, [| 0; 1; 2 |])`` () =
486 | (3y, [| 0uy; 1uy; 2uy |]) ||> Packer.packExt |> assertEquivalentTo [| 0xD6uy; 0x03uy; 0x00uy; 0x01uy; 0x02uy |]
487 |
488 | []
489 | let ``Should return 0xD60400010203 with passing (4, [| 0; 1; 2; 3 |])`` () =
490 | (4y, [| 0uy; 1uy; 2uy; 3uy |]) ||> Packer.packExt |> assertEquivalentTo [| 0xD6uy; 0x04uy; 0x00uy; 0x01uy; 0x02uy; 0x03uy |]
491 |
492 | []
493 | let ``Should return 0xD7050001020304 with passing (5, [| 0 .. 4 |])`` () =
494 | (5y, [| 0uy .. 4uy |]) ||> Packer.packExt |> assertEquivalentTo [| 0xD7uy; 0x05uy; 0x00uy; 0x01uy; 0x02uy; 0x03uy; 0x04uy |]
495 |
496 | []
497 | let ``Should return 0xD70600010120304050607 with passing (6, [| 0 .. 7 |])`` () =
498 | (6y, [| 0uy .. 7uy |]) ||> Packer.packExt |> assertEquivalentTo [| 0xD7uy; 0x06uy; 0x00uy; 0x01uy; 0x02uy; 0x03uy; 0x04uy; 0x05uy; 0x06uy; 0x07uy |]
499 |
500 | []
501 | let ``Should return 0xD807000102030405060708 with passing (7, [| 0 .. 8 |])`` () =
502 | (7y, [| 0uy .. 8uy |]) ||> Packer.packExt |> assertEquivalentTo [| 0xD8uy; 0x07uy; 0x00uy; 0x01uy; 0x02uy; 0x03uy
503 | 0x04uy; 0x05uy; 0x06uy; 0x07uy; 0x08uy |]
504 |
505 | []
506 | let ``Should return 0xD808000102030405060708090A0B0C0D0E0F with passing (8, [| 0 .. 15 |])`` () =
507 | (8y, [| 0uy .. 15uy |]) ||> Packer.packExt |> assertEquivalentTo [| 0xD8uy; 0x08uy; 0x00uy; 0x01uy; 0x02uy; 0x03uy; 0x04uy; 0x05uy; 0x06uy
508 | 0x07uy; 0x08uy; 0x09uy; 0x0Auy; 0x0Buy; 0x0Cuy; 0x0Duy; 0x0Euy; 0x0Fuy |]
509 |
510 | []
511 | let ``Should return byte[] and its format header is 0xC7 and its length is 20 with passing (9, [| 0 .. 16 |])`` () =
512 | let sut = (9y, [| 0uy .. 16uy |]) ||> Packer.packExt
513 | sut.Length |> assertEqualTo 20
514 | sut.[0..1] |> assertEquivalentTo [| 0xC7uy; 0x11uy |]
515 |
516 | []
517 | let ``Should return byte[] and its format header is 0xC7 and its length is 258 with passing (10, [| 0 .. 254 |])`` () =
518 | let sut = (10y, [| 0uy .. 254uy |]) ||> Packer.packExt
519 | sut.Length |> assertEqualTo 258
520 | sut.[0..1] |> assertEquivalentTo [| 0xC7uy; 0xFFuy |]
521 |
522 | []
523 | let ``Should return byte[] and its format header is 0xC8 and its length is 260 with passing (11, [| 0 .. 255 |])`` () =
524 | let sut = (11y, [| 0uy .. 255uy |]) ||> Packer.packExt
525 | sut.Length |> assertEqualTo 260
526 | sut.[0..2] |> assertEquivalentTo [| 0xC8uy; 0x01uy; 0x00uy |]
527 |
528 | []
529 | let ``Should return byte[] and its format header is 0xC8 and its length is 65539 with passing (12, 65535-length array)`` () =
530 | let sut = (12y, (Array.create 65535 0uy)) ||> Packer.packExt
531 | sut.Length |> assertEqualTo 65539
532 | sut.[0..2] |> assertEquivalentTo [| 0xC8uy; 0xFFuy; 0xFFuy |]
533 |
534 | []
535 | let ``Should return byte[] and its format header is 0xC9 and its length is 65542 with passing (13, 65536-length array)`` () =
536 | let sut = (13y, (Array.create 65536 0uy)) ||> Packer.packExt
537 | sut.Length |> assertEqualTo 65542
538 | sut.[0..4] |> assertEquivalentTo [| 0xC9uy; 0x00uy; 0x01uy; 0x00uy; 0x00uy |]
539 |
540 | []
541 | module WhenUsingPacker =
542 | []
543 | let ``Should return 0x01C403000102 with passing [Value.UInt8 1; Value.Bin [0x00; 0x01; 0x02]]`` () =
544 | [|Value.UInt8 1uy; Value.Bin [| 0x00uy; 0x01uy; 0x02uy |] |] |> Packer.pack |> assertEquivalentTo [| 0x01uy; 0xC4uy; 0x03uy; 0x00uy; 0x01uy; 0x02uy |]
--------------------------------------------------------------------------------
/MsgPack/Unpacker.fs:
--------------------------------------------------------------------------------
1 | namespace MsgPack
2 |
3 | module Unpacker =
4 | open System.Collections.Generic
5 |
6 | type internal Sequencials =
7 | | ArrayStore of int * Value []
8 | | MapStore of int * Value * Map
9 |
10 | type Bytes(bs:byte[])=
11 | let mutable _ind=0
12 | member this.Item with get i=bs.[_ind+i]
13 | member this.IncInd d= _ind<-_ind+d;this
14 | member this.Length=bs.Length-_ind
15 | member this.Dice(startI,endI)=bs.[_ind+startI.._ind+endI]
16 |
17 | []
18 | let unpack (bs:byte[]) =
19 | let bs=Bytes(bs)
20 | let raiseMessagePackException () = MessagePackException("Attempt to unpack with non-compatible type") |> raise
21 |
22 | let toUTF8Str (bytes:byte[])=System.Text.Encoding.UTF8.GetString(bytes,0,bytes.Length)
23 |
24 | let appendValue (newValue: Value) (sequencials: Stack) (values: List) =
25 | let mutable nv, doLoop = newValue, true
26 | while doLoop do
27 | if sequencials.Count > 0 then
28 | let elm = sequencials.Pop()
29 | match elm with
30 | | ArrayStore (count, arrayValues) ->
31 | arrayValues.[arrayValues.Length - count] <- nv
32 | let newCount = count - 1
33 | if newCount = 0 then
34 | nv <- Value.Array arrayValues
35 | else
36 | sequencials.Push(ArrayStore(newCount, arrayValues))
37 | doLoop <- false
38 | | MapStore (count, Value.Nil, mapValues) ->
39 | sequencials.Push(MapStore(count, newValue, mapValues))
40 | doLoop <- false
41 | | MapStore (count, key, mapValues) ->
42 | let newMap = Map.add key newValue mapValues
43 | let newCount = count - 1
44 | if newCount = 0 then
45 | nv <- Value.Map newMap
46 | else
47 | sequencials.Push(MapStore(newCount, Value.Nil, newMap))
48 | doLoop <- false
49 | else
50 | values.Add(nv)
51 | doLoop <- false
52 | sequencials, values
53 |
54 | let _unpackPositiveFixint (bytes: Bytes) (sequencials: Stack) (values: List) =
55 | let ars, vs = appendValue (Value.UInt8 bytes.[0]) sequencials values
56 | bytes.IncInd 1, ars, vs
57 |
58 | let _unpackFixmap (bytes: Bytes) (sequencials: Stack) =
59 | let length = int(bytes.[0] &&& 0b00001111uy)
60 | if bytes.Length - 1 >= length then
61 | sequencials.Push(MapStore(length, Value.Nil, Map.ofList []))
62 | bytes.IncInd 1, sequencials
63 | else
64 | raiseMessagePackException ()
65 |
66 | let _unpackFixarray (bytes: Bytes) (sequencials: Stack) =
67 | let length = int(bytes.[0] &&& 0b00001111uy)
68 | if bytes.Length - 1 >= length then
69 | sequencials.Push(ArrayStore(length, Array.init length (fun _ -> Value.Nil)))
70 | bytes.IncInd 1, sequencials
71 | else
72 | raiseMessagePackException ()
73 |
74 | let _unpackFixstr (bytes: Bytes) (sequencials: Stack) (values: List) =
75 | let length = int(bytes.[0] &&& 0b00011111uy)
76 | if bytes.Length - 1 >= length then
77 | // let newValue = System.Text.Encoding.UTF8.GetString(withStartCnt<|bytes.Dice(1,length)) |> Value.String
78 | let newValue = toUTF8Str(bytes.Dice(1,length)) |> Value.String
79 | let ars, vs = appendValue newValue sequencials values
80 | bytes.IncInd (length+1), ars, vs
81 | else
82 | raiseMessagePackException ()
83 |
84 | let _unpackNil (bytes: Bytes) (sequencials: Stack) (values: List) =
85 | let ars, vs = appendValue Value.Nil sequencials values
86 | bytes.IncInd 1, ars, vs
87 |
88 | let _unpackFalse (bytes: Bytes) (sequencials: Stack) (values: List) =
89 | let ars, vs = appendValue (Value.Bool false) sequencials values
90 | bytes.IncInd 1, ars, vs
91 |
92 | let _unpackTrue (bytes: Bytes) (sequencials: Stack) (values: List) =
93 | let ars, vs = appendValue (Value.Bool true) sequencials values
94 | bytes.IncInd 1, ars, vs
95 |
96 | let _unpackBin8 (bytes: Bytes) (sequencials: Stack) (values: List) =
97 | if bytes.Length >= 2 then
98 | let length = int(bytes.[1])
99 | if bytes.Length - 2 >= length then
100 | let newValue = Value.Bin <|bytes.Dice(2,(length+1))
101 | let ars, vs = appendValue newValue sequencials values
102 | bytes.IncInd (length+2), ars, vs
103 | else
104 | raiseMessagePackException ()
105 | else
106 | raiseMessagePackException ()
107 |
108 | let _unpackBin16 (bytes: Bytes) (sequencials: Stack) (values: List) =
109 | if bytes.Length >= 3 then
110 | let length = int(bytes.[1]) * 256 +
111 | int(bytes.[2])
112 | if bytes.Length - 3 >= length then
113 | let newValue = Value.Bin <|bytes.Dice(3,length+2)
114 | let ars, vs = appendValue newValue sequencials values
115 | bytes.IncInd (length+3), ars, vs
116 | else
117 | raiseMessagePackException ()
118 | else
119 | raiseMessagePackException ()
120 |
121 | let _unpackBin32 (bytes: Bytes) (sequencials: Stack) (values: List) =
122 | if bytes.Length >= 5 then
123 | let length = int(bytes.[1]) * 16777216 +
124 | int(bytes.[2]) * 65536 +
125 | int(bytes.[3]) * 256 +
126 | int(bytes.[4])
127 | if bytes.Length - 5 >= length then
128 | let newValue = Value.Bin <|bytes.Dice(5,length+4)
129 | let ars, vs = appendValue newValue sequencials values
130 | bytes.IncInd (length+5), ars, vs
131 | else
132 | raiseMessagePackException ()
133 | else
134 | raiseMessagePackException ()
135 |
136 | let _unpackExt8 (bytes: Bytes) (sequencials: Stack