Collection of DPF-based plugins for packaging
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
4.0KB

  1. #include "extra/Base64.hpp"
  2. #include "extra/String.hpp"
  3. int main(int argc, char* argv[])
  4. {
  5. if (argc != 2)
  6. {
  7. d_stdout("usage: %s [base64-dpf-state]", argv[0]);
  8. return 1;
  9. }
  10. const std::vector<uint8_t> data(d_getChunkFromBase64String(argv[1]));
  11. if (data.empty())
  12. {
  13. printf("{}\n");
  14. return 0;
  15. }
  16. String key, value;
  17. bool firstValue = true;
  18. bool hasValue = false;
  19. bool fillingKey = true; // if filling key or value
  20. char queryingType = 'i'; // can be 'n', 's' or 'p' (none, states, parameters)
  21. const char* const buffer = reinterpret_cast<const char*>(data.data());
  22. printf("{");
  23. for (size_t i = 0; i < data.size(); ++i)
  24. {
  25. // found terminator, stop here
  26. if (buffer[i] == '\xfe')
  27. {
  28. break;
  29. }
  30. // append to temporary vars
  31. if (fillingKey)
  32. {
  33. key += buffer + i;
  34. }
  35. else
  36. {
  37. value += buffer + i;
  38. hasValue = true;
  39. }
  40. // increase buffer offset by length of string
  41. i += std::strlen(buffer + i);
  42. // if buffer offset points to null, we found the end of a string, lets check
  43. if (buffer[i] == '\0')
  44. {
  45. // special keys
  46. if (key == "__dpf_state_begin__")
  47. {
  48. DISTRHO_SAFE_ASSERT_INT_RETURN(queryingType == 'i' || queryingType == 'n', queryingType, 1);
  49. if (queryingType == 'n')
  50. printf(",");
  51. printf("\n \"states\": {");
  52. queryingType = 's';
  53. key.clear();
  54. value.clear();
  55. firstValue = true;
  56. hasValue = false;
  57. continue;
  58. }
  59. if (key == "__dpf_state_end__")
  60. {
  61. DISTRHO_SAFE_ASSERT_INT_RETURN(queryingType == 's', queryingType, 1);
  62. printf("\n }");
  63. queryingType = 'n';
  64. key.clear();
  65. value.clear();
  66. hasValue = false;
  67. continue;
  68. }
  69. if (key == "__dpf_parameters_begin__")
  70. {
  71. DISTRHO_SAFE_ASSERT_INT_RETURN(queryingType == 'i' || queryingType == 'n', queryingType, 1);
  72. if (queryingType == 'n')
  73. printf(",");
  74. printf("\n \"parameters\": {");
  75. queryingType = 'p';
  76. key.clear();
  77. value.clear();
  78. firstValue = true;
  79. hasValue = false;
  80. continue;
  81. }
  82. if (key == "__dpf_parameters_end__")
  83. {
  84. DISTRHO_SAFE_ASSERT_INT_RETURN(queryingType == 'p', queryingType, 1);
  85. printf("\n }");
  86. queryingType = 'x';
  87. key.clear();
  88. value.clear();
  89. hasValue = false;
  90. continue;
  91. }
  92. // no special key, swap between reading real key and value
  93. fillingKey = !fillingKey;
  94. // if there is no value yet keep reading until we have one
  95. if (! hasValue)
  96. continue;
  97. if (key == "__dpf_program__")
  98. {
  99. DISTRHO_SAFE_ASSERT_INT_RETURN(queryingType == 'i', queryingType, 1);
  100. queryingType = 'n';
  101. printf("\n \"program\": %s", value.buffer());
  102. }
  103. else if (queryingType == 's')
  104. {
  105. if (! firstValue)
  106. printf(",");
  107. // TODO safely encode value as json compatible string
  108. printf("\n \"%s\": %s", key.buffer(), value.buffer());
  109. }
  110. else if (queryingType == 'p')
  111. {
  112. if (! firstValue)
  113. printf(",");
  114. printf("\n \"%s\": %s", key.buffer(), value.buffer());
  115. }
  116. key.clear();
  117. value.clear();
  118. firstValue = hasValue = false;
  119. }
  120. }
  121. printf("\n}\n");
  122. return 0;
  123. }