| @@ -175,64 +175,59 @@ constexpr unsigned processBeginStringOffset = sizeof(PROCESS_BEGIN_STRING); | |||
| #undef PROCESS_BEGIN_STRING | |||
| template <typename... Ts> | |||
| static void doAppend(char*& buf, int& size, const char* fmt, Ts... vals) { | |||
| static void doAppend(char*& buf, const char* fmt, Ts... vals) { | |||
| #pragma GCC diagnostic push | |||
| #pragma GCC diagnostic ignored "-Wformat-security" | |||
| auto result = std::snprintf(buf, size, fmt, vals...); | |||
| buf += std::sprintf(buf, fmt, vals...); | |||
| #pragma GCC diagnostic pop | |||
| buf += result; | |||
| size -= result; | |||
| } | |||
| const char* SC_VcvPrototypeClient::buildScProcessBlockString(const ProcessBlock* block) const noexcept { | |||
| auto* buf = processBlockStringScratchBuf + processBeginStringOffset - 1; | |||
| int size = sizeof(processBlockStringScratchBuf) - processBeginStringOffset + 1; | |||
| // Perhaps imprudently assuming snprintf never returns a negative code | |||
| doAppend(buf, size, "%.6f,%.6f,%d,", block->sampleRate, block->sampleTime, block->bufferSize); | |||
| doAppend(buf, "%.6f,%.6f,%d,", block->sampleRate, block->sampleTime, block->bufferSize); | |||
| auto&& appendInOutArray = [&buf, &size](const int bufferSize, const float (&data)[NUM_ROWS][MAX_BUFFER_SIZE]) { | |||
| doAppend(buf, size, "["); | |||
| auto&& appendInOutArray = [&buf](const int bufferSize, const float (&data)[NUM_ROWS][MAX_BUFFER_SIZE]) { | |||
| doAppend(buf, "["); | |||
| for (int i = 0; i < NUM_ROWS; ++i) { | |||
| doAppend(buf, size, "FloatArray["); | |||
| doAppend(buf, "FloatArray["); | |||
| for (int j = 0; j < bufferSize; ++j) { | |||
| doAppend(buf, size, "%g%c", data[i][j], j == bufferSize - 1 ? ' ' : ','); | |||
| doAppend(buf, "%g%c", data[i][j], j == bufferSize - 1 ? ' ' : ','); | |||
| } | |||
| doAppend(buf, size, "]%c", i == NUM_ROWS - 1 ? ' ' : ','); | |||
| doAppend(buf, "]%c", i == NUM_ROWS - 1 ? ' ' : ','); | |||
| } | |||
| doAppend(buf, size, "],"); | |||
| doAppend(buf, "],"); | |||
| }; | |||
| appendInOutArray(block->bufferSize, block->inputs); | |||
| appendInOutArray(block->bufferSize, block->outputs); | |||
| // knobs | |||
| doAppend(buf, size, "FloatArray["); | |||
| doAppend(buf, "FloatArray["); | |||
| for (int i = 0; i < NUM_ROWS; ++i) | |||
| doAppend(buf, size, "%g%c", block->knobs[i], i == NUM_ROWS - 1 ? ' ' : ','); | |||
| doAppend(buf, "%g%c", block->knobs[i], i == NUM_ROWS - 1 ? ' ' : ','); | |||
| // switches | |||
| doAppend(buf, size, "],["); | |||
| doAppend(buf, "],["); | |||
| for (int i = 0; i < NUM_ROWS; ++i) | |||
| doAppend(buf, size, "%s%c", block->switches[i] ? "true" : "false", i == NUM_ROWS - 1 ? ' ' : ','); | |||
| doAppend(buf, size, "]"); | |||
| doAppend(buf, "%s%c", block->switches[i] ? "true" : "false", i == NUM_ROWS - 1 ? ' ' : ','); | |||
| doAppend(buf, "]"); | |||
| // lights, switchlights | |||
| auto&& appendLightsArray = [&buf, &size](const float (&array)[NUM_ROWS][3]) { | |||
| doAppend(buf, size, ",["); | |||
| auto&& appendLightsArray = [&buf](const float (&array)[NUM_ROWS][3]) { | |||
| doAppend(buf, ",["); | |||
| for (int i = 0; i < NUM_ROWS; ++i) { | |||
| doAppend(buf, size, "FloatArray[%g,%g,%g]%c", array[i][0], array[i][1], array[i][2], | |||
| doAppend(buf, "FloatArray[%g,%g,%g]%c", array[i][0], array[i][1], array[i][2], | |||
| i == NUM_ROWS - 1 ? ' ' : ','); | |||
| } | |||
| doAppend(buf, size, "]"); | |||
| doAppend(buf, "]"); | |||
| }; | |||
| appendLightsArray(block->lights); | |||
| appendLightsArray(block->switchLights); | |||
| doAppend(buf, size, "));"); | |||
| // printf("%s\nWrote %lu, %u remaining", processBlockStringScratchBuf, buf - processBlockStringScratchBuf, size); | |||
| doAppend(buf, "));"); | |||
| return processBlockStringScratchBuf; | |||
| } | |||