@@ -5,73 +5,88 @@ open System.Text.Json
5
5
open System.Text .Json .Nodes
6
6
7
7
module MSDPLibrary =
8
- type Trigger =
9
- | NULL = 0 uy
10
- | MSDP_ VAR = 1 uy
11
- | MSDP_ VAL = 2 uy
12
- | MSDP_ TABLE_ OPEN = 3 uy
13
- | MSDP_ TABLE_ CLOSE = 4 uy
14
- | MSDP_ ARRAY_ OPEN = 5 uy
15
- | MSDP_ ARRAY_ CLOSE = 6 uy
8
+ type Trigger =
9
+ | NULL = 0 uy
10
+ | MSDP_ VAR = 1 uy
11
+ | MSDP_ VAL = 2 uy
12
+ | MSDP_ TABLE_ OPEN = 3 uy
13
+ | MSDP_ TABLE_ CLOSE = 4 uy
14
+ | MSDP_ ARRAY_ OPEN = 5 uy
15
+ | MSDP_ ARRAY_ CLOSE = 6 uy
16
16
17
- [<TailCall>]
18
- let rec private MSDPScanTailRec ( root : obj , array : byte seq , encoding : Encoding ) =
19
- let rec scan accRoot accArray =
20
- if Seq.length accArray = 0 then ( accRoot, accArray)
21
- else
22
- match accArray |> Seq.head with
23
- | 1 uy ->
24
- let key = encoding.GetString( accArray |> Seq.skip( 1 ) |> Seq.takeWhile( fun x -> x <> byte Trigger.MSDP_ VAL) |> Array.ofSeq)
25
- let ( calculatedValue , leftoverArray ) = scan root ( accArray |> Seq.skip( 1 ) |> Seq.skipWhile( fun x -> x <> byte Trigger.MSDP_ VAL))
26
- scan (( accRoot :?> Map< string, obj>) .Add( key, calculatedValue)) leftoverArray
27
- | 2 uy ->
28
- if accRoot :? Map< string, obj> then
29
- scan ( Map< string, obj> []) ( accArray |> Seq.skip( 1 ))
30
- elif accRoot :? List< obj> then
31
- let ( calculatedValue , leftoverArray ) = scan ( Map< string, obj> []) ( accArray |> Seq.skip( 1 ))
32
- scan (( accRoot :?> List< obj>) @ [ calculatedValue]) leftoverArray
33
- else
34
- scan accRoot ( accArray |> Seq.skip( 1 ))
35
- | 3 uy ->
36
- scan ( Map< string, obj> []) ( accArray |> Seq.skip( 1 ))
37
- | 5 uy ->
38
- scan ( List< obj>. Empty) ( accArray |> Seq.skip( 1 ))
39
- | 4 uy | 6 uy ->
40
- ( accRoot, accArray |> Seq.skip( 1 ))
41
- | _ ->
42
- ( encoding.GetString( accArray |> Seq.takeWhile( fun x -> x > 6 uy) |> Array.ofSeq), accArray |> Seq.skipWhile( fun x -> x > 6 uy))
43
- scan root array
17
+ let emptyMap : Map < string , obj > = Map< string, obj> []
18
+
19
+ let MSDPVal : byte = byte Trigger.MSDP_ VAL
44
20
45
- let public MSDPScan ( array : byte seq , encoding ) =
46
- let result , _ = MSDPScanTailRec( Map< string, obj> [], array, encoding)
47
- result
21
+ [<TailCall>]
22
+ let rec private MSDPScanTailRec ( root : obj , array : byte seq , encoding : Encoding ) =
23
+ let rec scanRec accRoot accArray =
24
+ if Seq.length accArray = 0 then
25
+ ( accRoot, accArray)
26
+ else
27
+ match accArray |> Seq.head with
28
+ | 1 uy ->
29
+ let key =
30
+ encoding.GetString(
31
+ accArray |> Seq.skip 1 |> Seq.takeWhile ( fun x -> x <> MSDPVal) |> Array.ofSeq
32
+ )
48
33
49
- let parseJsonRoot ( jsonRootNode : JsonNode , encoding : Encoding ) =
50
- let rec parseJsonValue ( jsonNode : JsonNode ) =
51
- match jsonNode.GetValueKind() with
52
- | JsonValueKind.Object ->
53
- let parsedObj =
54
- jsonNode.AsObject()
55
- |> Seq.map ( fun prop ->
56
- let key = prop.Key
57
- let value = parseJsonValue prop.Value
58
- [ byte Trigger.MSDP_ VAR] @ ( encoding.GetBytes( key) |> List.ofArray) @ [ byte Trigger.MSDP_ VAL] @ value
59
- ) |> List.concat
60
- [ byte Trigger.MSDP_ TABLE_ OPEN] @ parsedObj @ [( byte) Trigger.MSDP_ TABLE_ CLOSE]
61
- | JsonValueKind.Array ->
62
- let parsedArr =
63
- jsonNode.AsArray()
64
- |> Seq.map ( fun prop -> [ byte Trigger.MSDP_ VAL] @ parseJsonValue( prop))
65
- |> List.ofSeq
66
- |> List.concat
67
- [ byte Trigger.MSDP_ ARRAY_ OPEN] @ parsedArr @ [ byte Trigger.MSDP_ ARRAY_ CLOSE]
68
- | JsonValueKind.String -> encoding.GetBytes( jsonNode.AsValue() .ToString()) |> List.ofArray
69
- | JsonValueKind.Number -> encoding.GetBytes( jsonNode.AsValue() .ToString()) |> List.ofArray
70
- | JsonValueKind.True -> encoding.GetBytes( " 1" ) |> List.ofArray
71
- | JsonValueKind.False -> encoding.GetBytes( " 0" ) |> List.ofArray
72
- | JsonValueKind.Null -> encoding.GetBytes( " -1" ) |> List.ofArray
73
- | _ -> failwith " Invalid JSON value"
74
- parseJsonValue jsonRootNode
34
+ let cv , rest =
35
+ scanRec root ( accArray |> Seq.skip 1 |> Seq.skipWhile ( fun x -> x <> MSDPVal))
75
36
76
- let public Report ( jsonString : string , encoding : Encoding ) =
77
- parseJsonRoot( JsonValue.Parse( jsonString), encoding) |> Array.ofList
37
+ scanRec (( accRoot :?> Map< string, obj>) .Add( key, cv)) rest
38
+ | 2 uy ->
39
+ match accRoot with
40
+ | :? Map< string, obj> -> scanRec emptyMap ( accArray |> Seq.skip 1 )
41
+ | :? List< obj> ->
42
+ let cv , rest = scanRec emptyMap ( accArray |> Seq.skip 1 )
43
+
44
+ scanRec (( accRoot :?> List< obj>) @ [ cv ]) rest
45
+ | _ -> scanRec accRoot ( accArray |> Seq.skip 1 )
46
+ | 3 uy -> scanRec emptyMap ( accArray |> Seq.skip 1 )
47
+ | 4 uy -> accRoot, accArray |> Seq.skip 1
48
+ | 5 uy -> scanRec [] ( accArray |> Seq.skip 1 )
49
+ | 6 uy -> accRoot, accArray |> Seq.skip 1
50
+ | _ ->
51
+ encoding.GetString( accArray |> Seq.takeWhile ( fun x -> x > 6 uy) |> Array.ofSeq),
52
+ accArray |> Seq.skipWhile ( fun x -> x > 6 uy)
53
+
54
+ scanRec root array
55
+
56
+ let public MSDPScan ( array : byte seq , encoding ) =
57
+ let result , _ = MSDPScanTailRec( emptyMap, array, encoding)
58
+ result
59
+
60
+ let parseJsonRoot ( jsonRootNode : JsonNode , encoding : Encoding ) =
61
+ let rec parseJsonValue ( jsonNode : JsonNode ) =
62
+ match jsonNode.GetValueKind() with
63
+ | JsonValueKind.Object ->
64
+ let parsedObj =
65
+ jsonNode.AsObject()
66
+ |> Seq.map ( fun prop ->
67
+ [ byte Trigger.MSDP_ VAR ]
68
+ @ ( encoding.GetBytes( prop.Key) |> List.ofArray)
69
+ @ [ byte Trigger.MSDP_ VAL ]
70
+ @ parseJsonValue prop.Value)
71
+ |> List.concat
72
+
73
+ [ byte Trigger.MSDP_ TABLE_ OPEN ] @ parsedObj @ [ byte Trigger.MSDP_ TABLE_ CLOSE ]
74
+ | JsonValueKind.Array ->
75
+ let parsedArr =
76
+ jsonNode.AsArray()
77
+ |> Seq.map ( fun prop -> [ byte Trigger.MSDP_ VAL ] @ parseJsonValue prop)
78
+ |> List.ofSeq
79
+ |> List.concat
80
+
81
+ [ byte Trigger.MSDP_ ARRAY_ OPEN ] @ parsedArr @ [ byte Trigger.MSDP_ ARRAY_ CLOSE ]
82
+ | JsonValueKind.String -> encoding.GetBytes( jsonNode.AsValue() .ToString()) |> List.ofArray
83
+ | JsonValueKind.Number -> encoding.GetBytes( jsonNode.AsValue() .ToString()) |> List.ofArray
84
+ | JsonValueKind.True -> encoding.GetBytes( " 1" ) |> List.ofArray
85
+ | JsonValueKind.False -> encoding.GetBytes( " 0" ) |> List.ofArray
86
+ | JsonValueKind.Null -> encoding.GetBytes( " -1" ) |> List.ofArray
87
+ | _ -> failwith " Invalid JSON value"
88
+
89
+ parseJsonValue jsonRootNode
90
+
91
+ let public Report ( jsonString : string , encoding : Encoding ) =
92
+ parseJsonRoot ( JsonValue.Parse( jsonString), encoding) |> Array.ofList
0 commit comments