22 int stat = 0, value = 0, code = 0;
23 const char *cur = b.data();
24 const char *end = b.data() + b.size();
25 auto [ptr_value, e] = std::from_chars(cur, end, stat);
26 if (e != std::errc{}) {
27 std::cerr <<
"failed to parse status bytesn\n";
31 while (cur != end && *cur ==
' ') {
35 auto [ptr_value2, e2] = std::from_chars(cur, end, code);
36 if (e2 != std::errc{}) {
37 std::cerr <<
"Failed to parse code\n";
41 while (cur != end && *cur ==
' ') {
44 auto [ptr3, e3] = std::from_chars(cur, end, value);
45 if (e3 != std::errc{}) {
46 std::cerr <<
"Error failed to pasre value\n";
50 std::cout <<
"Status: " << stat <<
" CC: " << code <<
" Value: " << value <<
"\n";
56 std::ifstream mapping_input(filename);
58 throw std::runtime_error(
"could not open MIDI map file: " + filename);
61 std::vector<MidiMapping> mappings;
63 std::size_t line_number = 0;
68 const std::size_t first = line.find_first_not_of(
" \t\r");
69 if (first == std::string::npos || line[first] ==
'#') {
73 throw std::runtime_error(
"MIDI map file contains too many mappings");
77 std::istringstream stream(line);
78 std::string action_pair;
84 if (!(stream >> action_pair >> open_brace >> status >> data1 >> data2 >> close_brace) || open_brace !=
'{' || close_brace !=
'}') {
85 throw std::runtime_error(
"invalid MIDI map entry at " + filename +
':' + std::to_string(line_number));
89 throw std::runtime_error(
"unexpected text in MIDI map at " + filename +
':' + std::to_string(line_number));
92 const std::size_t colon = action_pair.find(
':');
93 if (colon == std::string::npos || colon == 0 || colon + 1 >= action_pair.size() || action_pair.find(
':', colon + 1) != std::string::npos) {
94 throw std::runtime_error(
"invalid MIDI action pair at " + filename +
':' + std::to_string(line_number));
97 std::size_t primary_parsed = 0;
98 std::size_t secondary_parsed = 0;
102 primary = std::stoi(action_pair.substr(0, colon), &primary_parsed);
103 secondary = std::stoi(action_pair.substr(colon + 1), &secondary_parsed);
104 }
catch (
const std::exception &) {
105 throw std::runtime_error(
"invalid MIDI action code at " + filename +
':' + std::to_string(line_number));
107 if (primary_parsed != colon || secondary_parsed != action_pair.size() - colon - 1 || primary <= 0 || primary > 65535 || secondary < 0 || secondary > 65535 || status < 0 || status > 255 || data1 < 0 || data1 > 255 || data2 < 0 || data2 > 255) {
108 throw std::runtime_error(
"MIDI map value outside its valid range at " + filename +
':' + std::to_string(line_number));
111 mappings.push_back({primary, secondary,
static_cast<unsigned char>(status),
static_cast<unsigned char>(data1),
static_cast<unsigned char>(data2)});