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
3.0KB

  1. #pragma once
  2. #include <common.hpp>
  3. #include <jansson.h>
  4. namespace rack {
  5. /** JSON helpers */
  6. namespace json {
  7. /** Checks that a JSON type can be cast to the C++ type */
  8. template <typename T>
  9. bool is(json_t* valueJ);
  10. template <>
  11. inline bool is<std::string>(json_t* valueJ) {
  12. return json_is_string(valueJ);
  13. }
  14. template <>
  15. inline bool is<json_int_t>(json_t* valueJ) {
  16. return json_is_integer(valueJ);
  17. }
  18. template <>
  19. inline bool is<int>(json_t* valueJ) {
  20. return json_is_integer(valueJ);
  21. }
  22. template <>
  23. inline bool is<double>(json_t* valueJ) {
  24. return json_is_number(valueJ);
  25. }
  26. template <>
  27. inline bool is<float>(json_t* valueJ) {
  28. return json_is_number(valueJ);
  29. }
  30. template <>
  31. inline bool is<bool>(json_t* valueJ) {
  32. return json_is_boolean(valueJ);
  33. }
  34. /** Converts C++ types to the JSON type */
  35. template <typename T>
  36. json_t* to(T value);
  37. template <>
  38. inline json_t* to(const std::string& value) {
  39. return json_stringn(value.c_str(), value.size());
  40. }
  41. template <>
  42. inline json_t* to(json_int_t value) {
  43. return json_integer(value);
  44. }
  45. template <>
  46. inline json_t* to(int value) {
  47. return json_integer(value);
  48. }
  49. template <>
  50. inline json_t* to(double value) {
  51. return json_real(value);
  52. }
  53. template <>
  54. inline json_t* to(float value) {
  55. return json_real(value);
  56. }
  57. template <>
  58. inline json_t* to(bool value) {
  59. return json_boolean(value);
  60. }
  61. /** Converts the JSON type to C++ types */
  62. template <typename T>
  63. T from(json_t* valueJ);
  64. template <>
  65. inline std::string from(json_t* valueJ) {
  66. return std::string(json_string_value(valueJ), json_string_length(valueJ));
  67. }
  68. template <>
  69. inline json_int_t from(json_t* valueJ) {
  70. return json_integer_value(valueJ);
  71. }
  72. template <>
  73. inline int from(json_t* valueJ) {
  74. return json_integer_value(valueJ);
  75. }
  76. template <>
  77. inline double from(json_t* valueJ) {
  78. return json_number_value(valueJ);
  79. }
  80. template <>
  81. inline float from(json_t* valueJ) {
  82. return json_number_value(valueJ);
  83. }
  84. template <>
  85. inline bool from(json_t* valueJ) {
  86. return json_boolean_value(valueJ);
  87. }
  88. /** Helper template function for array functions */
  89. inline int multiplyDims() {
  90. return 1;
  91. }
  92. template <typename... Dims>
  93. int multiplyDims(int dim, Dims... dims) {
  94. return dim * multiplyDims(dims...);
  95. }
  96. /** Converts a C++ array to a JSON multidimensional array */
  97. template <typename T>
  98. json_t* toArray(const T* x) {
  99. return to(*x);
  100. }
  101. template <typename T, typename... Dims>
  102. json_t* toArray(const T* x, int dim, Dims... dims) {
  103. int stride = multiplyDims(dims...);
  104. json_t* arrayJ = json_array();
  105. for (int i = 0; i < dim; i++) {
  106. json_array_insert_new(arrayJ, i, toArray(&x[i * stride], dims...));
  107. }
  108. return arrayJ;
  109. }
  110. /** Converts a JSON multidimensional array to a C++ array */
  111. template <typename T>
  112. void fromArray(json_t* arrayJ, T* x) {
  113. *x = from<T>(arrayJ);
  114. }
  115. template <typename T, typename... Dims>
  116. void fromArray(json_t* arrayJ, T* x, int dim, Dims... dims) {
  117. int stride = multiplyDims(dims...);
  118. for (int i = 0; i < dim; i++) {
  119. json_t* elJ = json_array_get(arrayJ, i);
  120. if (elJ) {
  121. fromArray(elJ, &x[i * stride], dims...);
  122. }
  123. }
  124. }
  125. } // namespace json
  126. } // namespace rack