MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
OscParser.cpp
Go to the documentation of this file.
1#include "OscParser.hpp"
2
4
5namespace MayaFlux::Core {
6
7std::optional<InputValue> OscParser::parse(const uint8_t* data, size_t size,
8 uint32_t device_id)
9{
10 if (size < 4 || data[0] != '/') {
11 return std::nullopt;
12 }
13
14 size_t offset = 0;
15
16 std::string address = Transitive::Protocol::read_string(data, size, offset);
17 if (address.empty() || offset >= size) {
18 return std::nullopt;
19 }
20
21 std::string type_tags;
22 if (offset < size && data[offset] == ',') {
23 type_tags = Transitive::Protocol::read_string(data, size, offset);
24 if (!type_tags.empty() && type_tags[0] == ',') {
25 type_tags = type_tags.substr(1);
26 }
27 }
28
29 std::vector<InputValue::OSCArg> arguments;
30 arguments.reserve(type_tags.size());
31
32 for (char tag : type_tags) {
33 if (offset > size) {
34 break;
35 }
36
37 switch (tag) {
38 case 'i':
39 if (offset + 4 <= size) {
40 arguments.emplace_back(Transitive::Protocol::read_int32(data, offset));
41 }
42 break;
43
44 case 'f':
45 if (offset + 4 <= size) {
46 arguments.emplace_back(Transitive::Protocol::read_float(data, offset));
47 }
48 break;
49
50 case 's':
51 arguments.emplace_back(Transitive::Protocol::read_string(data, size, offset));
52 break;
53
54 case 'b':
55 arguments.emplace_back(Transitive::Protocol::read_blob(data, size, offset));
56 break;
57
58 default:
59 break;
60 }
61 }
62
63 return InputValue::make_osc(std::move(address), std::move(arguments), device_id);
64}
65
66std::vector<uint8_t> OscParser::serialize(const std::string& address,
67 const std::vector<InputValue::OSCArg>& args)
68{
69 if (address.empty() || address[0] != '/') {
70 return {};
71 }
72
73 std::vector<uint8_t> out;
74 out.reserve(256);
75
77
78 std::string type_tags = ",";
79 for (const auto& arg : args) {
80 std::visit([&type_tags](const auto& val) {
81 using T = std::decay_t<decltype(val)>;
82 if constexpr (std::is_same_v<T, int32_t>) {
83 type_tags += 'i';
84 } else if constexpr (std::is_same_v<T, float>) {
85 type_tags += 'f';
86 } else if constexpr (std::is_same_v<T, std::string>) {
87 type_tags += 's';
88 } else if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
89 type_tags += 'b';
90 }
91 },
92 arg);
93 }
95
96 for (const auto& arg : args) {
97 std::visit([&out](const auto& val) {
98 using T = std::decay_t<decltype(val)>;
99 if constexpr (std::is_same_v<T, int32_t>) {
101 } else if constexpr (std::is_same_v<T, float>) {
103 } else if constexpr (std::is_same_v<T, std::string>) {
105 } else if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
107 }
108 },
109 arg);
110 }
111
112 return out;
113}
114
115} // namespace MayaFlux::Core
Range size
static std::optional< InputValue > parse(const uint8_t *data, size_t size, uint32_t device_id=0)
Parse a single OSC message from raw bytes.
Definition OscParser.cpp:7
static std::vector< uint8_t > serialize(const std::string &address, const std::vector< InputValue::OSCArg > &args)
Serialize an OSC message to wire format.
Definition OscParser.cpp:66
void write_int32(std::vector< uint8_t > &out, int32_t val)
Append a big-endian int32.
void write_blob(std::vector< uint8_t > &out, const std::vector< uint8_t > &blob)
Append a length-prefixed blob padded to 4-byte boundary.
std::vector< uint8_t > read_blob(const uint8_t *data, size_t max_len, size_t &offset)
Read a length-prefixed blob from a byte buffer.
int32_t read_int32(const uint8_t *data, size_t &offset)
Read a big-endian int32 from a byte buffer.
void write_string(std::vector< uint8_t > &out, const std::string &str)
Append a null-terminated string padded to 4-byte boundary.
std::string read_string(const uint8_t *data, size_t max_len, size_t &offset)
Read a null-terminated string from a byte buffer.
float read_float(const uint8_t *data, size_t &offset)
Read a big-endian IEEE 754 float from a byte buffer.
void write_float(std::vector< uint8_t > &out, float val)
Append a big-endian IEEE 754 float.
static InputValue make_osc(std::string addr, std::vector< OSCArg > args, uint32_t dev_id)