18#include "CarlaStateUtils.hpp"
20#include "CarlaBackendUtils.hpp"
21#include "CarlaMathUtils.hpp"
33CARLA_BACKEND_START_NAMESPACE
40 static const int kLineWidth = 120;
43 const int length =
string.length();
44 const char*
const raw =
string.toUTF8();
48 for (;
i+kLineWidth <
length;
i += kLineWidth)
50 stream.
write(raw+
i, kLineWidth);
63static std::string
replaceStdString(
const std::string& original,
const std::string& before,
const std::string& after)
65 std::string::const_iterator current = original.begin(), end = original.end(), next;
68 for (; (next = std::search(current, end, before.begin(), before.end())) != end;)
70 retval.append(current, next);
72 current = next +
static_cast<ssize_t
>(before.size());
74 retval.append(current, next);
80 std::string string(cstring);
114 return carla_strdup(xmlSafeString(
string, toXml).toRawUTF8());
120CarlaStateSave::Parameter::Parameter()
noexcept
125 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
129 mappedRangeValid(
false),
131 mappedMaximum(1.0f) {}
136CarlaStateSave::Parameter::~Parameter()
noexcept
143 if (symbol !=
nullptr)
158CarlaStateSave::CustomData::~CustomData()
noexcept
170 if (
value !=
nullptr)
179 if (
type ==
nullptr ||
type[0] ==
'\0')
return false;
180 if (
key ==
nullptr ||
key [0] ==
'\0')
return false;
181 if (
value ==
nullptr)
return false;
188CarlaStateSave::CarlaStateSave()
noexcept
196 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
205 currentProgramIndex(-1),
206 currentProgramName(
nullptr),
208 currentMidiProgram(-1),
213CarlaStateSave::~CarlaStateSave()
noexcept
218void CarlaStateSave::clear()
noexcept
230 if (label !=
nullptr)
235 if (binary !=
nullptr)
240 if (currentProgramName !=
nullptr)
242 delete[] currentProgramName;
243 currentProgramName =
nullptr;
245 if (chunk !=
nullptr)
254 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
264 currentProgramIndex = -1;
265 currentMidiBank = -1;
266 currentMidiProgram = -1;
268 for (ParameterItenerator it = parameters.begin2(); it.valid(); it.next())
270 Parameter*
const stateParameter(it.getValue(
nullptr));
271 delete stateParameter;
274 for (CustomDataItenerator it = customData.begin2(); it.valid(); it.next())
276 CustomData*
const stateCustomData(it.getValue(
nullptr));
277 delete stateCustomData;
287bool CarlaStateSave::fillFromXmlElement(
const XmlElement*
const xmlElement)
295 const String& tagName(elem->getTagName());
300 if (tagName ==
"Info")
304 const String& tag(xmlInfo->getTagName());
305 const String text(xmlInfo->getAllSubText().trim());
309 else if (tag ==
"Name")
311 else if (tag ==
"Label" || tag ==
"URI" || tag ==
"Identifier" || tag ==
"Setup")
313 else if (tag ==
"Binary" || tag ==
"Filename")
315 else if (tag ==
"UniqueID")
316 uniqueId =
text.getLargeIntValue();
323 else if (tagName ==
"Data")
327 const String& tag(xmlData->getTagName());
328 const String text(xmlData->getAllSubText().trim());
333 if (tag ==
"Options")
339 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
340 else if (tag ==
"Active")
342 active = (
text ==
"Yes");
344 else if (tag ==
"DryWet")
346 dryWet = carla_fixedValue(0.0f, 1.0f,
text.getFloatValue());
348 else if (tag ==
"Volume")
350 volume = carla_fixedValue(0.0f, 1.27f,
text.getFloatValue());
352 else if (tag ==
"Balance-Left")
354 balanceLeft = carla_fixedValue(-1.0f, 1.0f,
text.getFloatValue());
356 else if (tag ==
"Balance-Right")
358 balanceRight = carla_fixedValue(-1.0f, 1.0f,
text.getFloatValue());
360 else if (tag ==
"Panning")
362 panning = carla_fixedValue(-1.0f, 1.0f,
text.getFloatValue());
364 else if (tag ==
"ControlChannel")
366 if (!
text.startsWithIgnoreCase(
"n"))
378 else if (tag ==
"CurrentProgramIndex")
382 currentProgramIndex =
value-1;
384 else if (tag ==
"CurrentProgramName")
392 else if (tag ==
"CurrentMidiBank")
396 currentMidiBank =
value-1;
398 else if (tag ==
"CurrentMidiProgram")
402 currentMidiProgram =
value-1;
408 else if (tag ==
"Parameter")
410 Parameter*
const stateParameter(
new Parameter());
411 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
412 bool hasMappedMinimum =
false, hasMappedMaximum =
false;
417 const String& pTag(xmlSubData->getTagName());
418 const String pText(xmlSubData->getAllSubText().trim());
422 const int index(pText.getIntValue());
424 stateParameter->index = index;
426 else if (pTag ==
"Name")
430 else if (pTag ==
"Symbol" || pTag ==
"Identifier")
434 else if (pTag ==
"Value")
436 stateParameter->dummy =
false;
437 stateParameter->value = pText.getFloatValue();
439 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
440 else if (pTag ==
"MidiChannel")
442 const int channel(pText.getIntValue());
444 stateParameter->midiChannel =
static_cast<uint8_t>(channel-1);
446 else if (pTag ==
"MidiCC")
448 const int cc(pText.getIntValue());
450 stateParameter->mappedControlIndex =
static_cast<int16_t>(cc);
452 else if (pTag ==
"MappedControlIndex")
454 const int ctrl(pText.getIntValue());
457 stateParameter->mappedControlIndex =
static_cast<int16_t>(ctrl);
459 else if (pTag ==
"MappedMinimum")
461 hasMappedMinimum =
true;
462 stateParameter->mappedMinimum = pText.getFloatValue();
464 else if (pTag ==
"MappedMaximum")
466 hasMappedMaximum =
true;
467 stateParameter->mappedMaximum = pText.getFloatValue();
472 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
473 if (hasMappedMinimum && hasMappedMaximum)
474 stateParameter->mappedRangeValid =
true;
477 parameters.append(stateParameter);
483 else if (tag ==
"CustomData")
490 const String& cTag(xmlSubData->getTagName());
499 if (stateCustomData->type ==
nullptr || stateCustomData->type[0] ==
'\0')
501 carla_stderr(
"Reading CustomData type failed");
502 delete stateCustomData;
509 const String& cTag(xmlSubData->getTagName());
510 String cText(xmlSubData->getAllSubText());
516 else if (cTag ==
"Value")
519 const int len = cText.length();
523 cText = cText.substring(1, len - 5);
530 if (stateCustomData->isValid())
532 customData.append(stateCustomData);
536 carla_stderr(
"Reading CustomData property failed, missing data");
537 delete stateCustomData;
544 else if (tag ==
"Chunk")
546 chunk = carla_strdup(
text.toRawUTF8());
565 infoXml <<
" <Info>\n";
566 infoXml <<
" <Type>" <<
String(
type !=
nullptr ?
type :
"") <<
"</Type>\n";
567 infoXml <<
" <Name>" << xmlSafeString(
name,
true) <<
"</Name>\n";
574 infoXml <<
" <Label>" << xmlSafeString(label,
true) <<
"</Label>\n";
577 infoXml <<
" <Binary>" << xmlSafeString(binary,
true) <<
"</Binary>\n";
578 infoXml <<
" <Label>" << xmlSafeString(label,
true) <<
"</Label>\n";
579 infoXml <<
" <UniqueID>" <<
water::int64(uniqueId) <<
"</UniqueID>\n";
582 infoXml <<
" <Binary>" << xmlSafeString(binary,
true) <<
"</Binary>\n";
583 infoXml <<
" <Label>" << xmlSafeString(label,
true) <<
"</Label>\n";
586 infoXml <<
" <URI>" << xmlSafeString(label,
true) <<
"</URI>\n";
589 infoXml <<
" <Binary>" << xmlSafeString(binary,
true) <<
"</Binary>\n";
590 infoXml <<
" <UniqueID>" <<
water::int64(uniqueId) <<
"</UniqueID>\n";
593 infoXml <<
" <Binary>" << xmlSafeString(binary,
true) <<
"</Binary>\n";
594 infoXml <<
" <Label>" << xmlSafeString(label,
true) <<
"</Label>\n";
597 infoXml <<
" <Identifier>" << xmlSafeString(label,
true) <<
"</Identifier>\n";
600 infoXml <<
" <Binary>" << xmlSafeString(binary,
true) <<
"</Binary>\n";
601 infoXml <<
" <Identifier>" << xmlSafeString(label,
true) <<
"</Identifier>\n";
607 infoXml <<
" <Filename>" << xmlSafeString(binary,
true) <<
"</Filename>\n";
608 infoXml <<
" <Label>" << xmlSafeString(label,
true) <<
"</Label>\n";
611 infoXml <<
" <Filename>" << xmlSafeString(binary,
true) <<
"</Filename>\n";
614 infoXml <<
" <Filename>" << xmlSafeString(binary,
true) <<
"</Filename>\n";
615 infoXml <<
" <Setup>" << xmlSafeString(label,
true) <<
"</Setup>\n";
621 infoXml <<
" </Info>\n\n";
626 content <<
" <Data>\n";
628 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
632 dataXml <<
" <Active>" << (active ?
"Yes" :
"No") <<
"</Active>\n";
634 if (carla_isNotEqual(dryWet, 1.0f))
635 dataXml <<
" <DryWet>" <<
String(dryWet, 7) <<
"</DryWet>\n";
636 if (carla_isNotEqual(
volume, 1.0f))
637 dataXml <<
" <Volume>" <<
String(
volume, 7) <<
"</Volume>\n";
638 if (carla_isNotEqual(balanceLeft, -1.0f))
639 dataXml <<
" <Balance-Left>" <<
String(balanceLeft, 7) <<
"</Balance-Left>\n";
640 if (carla_isNotEqual(balanceRight, 1.0f))
641 dataXml <<
" <Balance-Right>" <<
String(balanceRight, 7) <<
"</Balance-Right>\n";
642 if (carla_isNotEqual(panning, 0.0f))
643 dataXml <<
" <Panning>" <<
String(panning, 7) <<
"</Panning>\n";
646 dataXml <<
" <ControlChannel>N</ControlChannel>\n";
648 dataXml <<
" <ControlChannel>" <<
int(ctrlChannel+1) <<
"</ControlChannel>\n";
650 dataXml <<
" <Options>0x" <<
String::toHexString(
static_cast<int>(options)) <<
"</Options>\n";
656 for (ParameterItenerator it = parameters.begin2(); it.valid(); it.next())
658 Parameter*
const stateParameter(it.getValue(
nullptr));
663 parameterXml <<
"\n";
664 parameterXml <<
" <Parameter>\n";
665 parameterXml <<
" <Index>" <<
String(stateParameter->index) <<
"</Index>\n";
666 parameterXml <<
" <Name>" << xmlSafeString(stateParameter->name,
true) <<
"</Name>\n";
668 if (stateParameter->symbol !=
nullptr && stateParameter->symbol[0] !=
'\0')
671 parameterXml <<
" <Identifier>" << xmlSafeString(stateParameter->symbol,
true) <<
"</Identifier>\n";
673 parameterXml <<
" <Symbol>" << xmlSafeString(stateParameter->symbol,
true) <<
"</Symbol>\n";
676 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
679 parameterXml <<
" <MidiChannel>" << stateParameter->midiChannel+1 <<
"</MidiChannel>\n";
680 parameterXml <<
" <MappedControlIndex>" << stateParameter->mappedControlIndex <<
"</MappedControlIndex>\n";
682 if (stateParameter->mappedRangeValid)
684 parameterXml <<
" <MappedMinimum>" <<
String(stateParameter->mappedMinimum, 15) <<
"</MappedMinimum>\n";
685 parameterXml <<
" <MappedMaximum>" <<
String(stateParameter->mappedMaximum, 15) <<
"</MappedMaximum>\n";
689 if (stateParameter->mappedControlIndex > 0 && stateParameter->mappedControlIndex <
MAX_MIDI_CONTROL)
690 parameterXml <<
" <MidiCC>" << stateParameter->mappedControlIndex <<
"</MidiCC>\n";
694 if (! stateParameter->dummy)
695 parameterXml <<
" <Value>" <<
String(stateParameter->value, 15) <<
"</Value>\n";
697 parameterXml <<
" </Parameter>\n";
699 content << parameterXml;
702 if (currentProgramIndex >= 0 && currentProgramName !=
nullptr && currentProgramName[0] !=
'\0')
705 if (currentProgramIndex > 0 || !
String(currentProgramName).equalsIgnoreCase(
"default"))
710 programXml <<
" <CurrentProgramIndex>" << currentProgramIndex+1 <<
"</CurrentProgramIndex>\n";
711 programXml <<
" <CurrentProgramName>" << xmlSafeString(currentProgramName,
true) <<
"</CurrentProgramName>\n";
713 content << programXml;
717 if (currentMidiBank >= 0 && currentMidiProgram >= 0)
721 midiProgramXml <<
"\n";
722 midiProgramXml <<
" <CurrentMidiBank>" << currentMidiBank+1 <<
"</CurrentMidiBank>\n";
723 midiProgramXml <<
" <CurrentMidiProgram>" << currentMidiProgram+1 <<
"</CurrentMidiProgram>\n";
725 content << midiProgramXml;
728 for (CustomDataItenerator it = customData.begin2(); it.valid(); it.next())
730 CustomData*
const stateCustomData(it.getValue(
nullptr));
736 customDataXml <<
"\n";
737 customDataXml <<
" <CustomData>\n";
738 customDataXml <<
" <Type>" << xmlSafeString(stateCustomData->type,
true) <<
"</Type>\n";
739 customDataXml <<
" <Key>" << xmlSafeString(stateCustomData->key,
true) <<
"</Key>\n";
741 if (std::strcmp(stateCustomData->type,
CUSTOM_DATA_TYPE_CHUNK) == 0 || std::strlen(stateCustomData->value) >= 128)
743 customDataXml <<
" <Value>\n";
745 customDataXml <<
"\n </Value>\n";
749 customDataXml <<
" <Value>";
751 customDataXml <<
"</Value>\n";
754 customDataXml <<
" </CustomData>\n";
756 content << customDataXml;
759 if (chunk !=
nullptr && chunk[0] !=
'\0')
764 chunkXml <<
"\n <Chunk>\n";
765 chunkXml << chunkSplt;
766 chunkXml <<
"\n </Chunk>\n";
771 content <<
" </Data>\n";
776CARLA_BACKEND_END_NAMESPACE
#define CARLA_SAFE_ASSERT_CONTINUE(cond)
Definition CarlaDefines.h:189
#define CARLA_SAFE_ASSERT_RETURN(cond, ret)
Definition CarlaDefines.h:190
unsigned int uint
Definition CarlaDefines.h:327
#define MAX_MIDI_CONTROL
Definition CarlaMIDI.h:24
#define MAX_MIDI_CHANNELS
Definition CarlaMIDI.h:21
static std::string xmlSafeStringFast(const char *const cstring, const bool toXml)
Definition CarlaStateUtils.cpp:78
static const char * xmlSafeStringCharDup(const String &string, const bool toXml)
Definition CarlaStateUtils.cpp:112
static std::string replaceStdString(const std::string &original, const std::string &before, const std::string &after)
Definition CarlaStateUtils.cpp:63
static CARLA_BACKEND_START_NAMESPACE void getNewLineSplittedString(MemoryOutputStream &stream, const String &string)
Definition CarlaStateUtils.cpp:38
#define noexcept
Definition DistrhoDefines.h:72
CAdPlugDatabase::CRecord::RecordType type
Definition adplugdb.cpp:93
static String toHexString(int number)
Definition String.cpp:1830
Definition MemoryOutputStream.h:42
void preallocate(size_t bytesToPreallocate)
Definition MemoryOutputStream.cpp:65
bool write(const void *, size_t) override
Definition MemoryOutputStream.cpp:92
virtual bool writeByte(char byte)
Definition OutputStream.cpp:51
Definition XmlElement.h:145
XmlElement * getNextElement() const noexcept
Definition XmlElement.h:464
XmlElement * getFirstChildElement() const noexcept
Definition XmlElement.h:436
register unsigned i
Definition inflate.c:1575
int retval
Definition inflate.c:947
PluginType
Definition CarlaBackend.h:614
struct _CustomData CustomData
Definition CarlaStateUtils.cpp:153
@ PLUGIN_CLAP
Definition CarlaBackend.h:689
@ PLUGIN_TYPE_COUNT
Definition CarlaBackend.h:694
@ PLUGIN_LV2
Definition CarlaBackend.h:638
@ PLUGIN_VST2
Definition CarlaBackend.h:643
@ PLUGIN_SFZ
Definition CarlaBackend.h:674
@ PLUGIN_JACK
Definition CarlaBackend.h:679
@ PLUGIN_INTERNAL
Definition CarlaBackend.h:623
@ PLUGIN_DLS
Definition CarlaBackend.h:659
@ PLUGIN_SF2
Definition CarlaBackend.h:669
@ PLUGIN_NONE
Definition CarlaBackend.h:618
@ PLUGIN_LADSPA
Definition CarlaBackend.h:628
@ PLUGIN_GIG
Definition CarlaBackend.h:664
@ PLUGIN_DSSI
Definition CarlaBackend.h:633
@ PLUGIN_AU
Definition CarlaBackend.h:654
@ PLUGIN_VST3
Definition CarlaBackend.h:648
@ PLUGIN_JSFX
Definition CarlaBackend.h:684
@ CONTROL_INDEX_MAX_ALLOWED
Definition CarlaBackend.h:877
@ CONTROL_INDEX_NONE
Definition CarlaBackend.h:857
@ CONTROL_INDEX_MIDI_LEARN
Definition CarlaBackend.h:872
static constexpr const char *const CUSTOM_DATA_TYPE_CHUNK
Definition CarlaBackend.h:497
static constexpr const uint PLUGIN_OPTIONS_NULL
Definition CarlaBackend.h:289
static PuglViewHint int value
Definition pugl.h:1708
static const char * name
Definition pugl.h:1582
short int16_t
Definition mid.cpp:96
unsigned char uint8_t
Definition mid.cpp:98
signed char int8_t
Definition mid.cpp:95
void clear(void *s)
Definition juce_FixedSizeFunction.h:71
@ label
Definition juce_AccessibilityRole.h:44
long long int64
Definition water.h:100
static float volume(float level)
Definition nekobee_voice_render.c:99
#define true
Definition ordinals.h:82
#define false
Definition ordinals.h:83
png_uint_32 length
Definition png.c:2247
const char * text
Definition swell-functions.h:167
ZCONST char * key
Definition crypt.c:587
typedef int(UZ_EXP MsgFn)()
#define const
Definition zconf.h:137