-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOscMessageParser.cs
More file actions
60 lines (47 loc) · 1.82 KB
/
OscMessageParser.cs
File metadata and controls
60 lines (47 loc) · 1.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using System;
using System.Collections.Generic;
namespace Suhock.Osc;
public sealed class OscMessageParser: IOscMessageParser
{
private readonly IOscArgumentParser _argumentParser;
public OscMessageParser() : this(new OscArgumentParser())
{
}
public OscMessageParser(IOscArgumentParser argumentParser)
{
_argumentParser = argumentParser;
}
public OscMessage ParseBytes(ReadOnlySpan<byte> bytes, out int length)
{
var segmentStart = bytes;
var address = OscUtil.ReadString(segmentStart, out var segmentLength);
length = segmentLength;
segmentStart = segmentStart[segmentLength..];
var typeTagString = OscUtil.ReadByteString(segmentStart, out segmentLength);
if (typeTagString.Length > 0 && typeTagString[0] == (byte)',')
{
// Only increase the length of the bytes used if this segment is a valid type tag string
length += segmentLength;
}
if (typeTagString.Length <= 1 || typeTagString[0] != (byte)',')
{
// Address was followed by: nothing, a type tag string specifying no arguments, or a non-standard
// value.
// Return a message with no arguments.
return new OscMessage(address);
}
var argList = new List<IOscArgument>(typeTagString.Length - 1);
for (var i = 1; i < typeTagString.Length; i++)
{
segmentStart = segmentStart[segmentLength..];
var arg = _argumentParser.FromBytes(typeTagString[i], segmentStart, out segmentLength);
if (arg == null)
{
throw new InvalidOperationException("Invalid message");
}
argList.Add(arg);
length += segmentLength;
}
return new OscMessage(address, argList);
}
}