diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md
index f4056f1584..3e122ddb93 100644
--- a/BREAKING_CHANGES.md
+++ b/BREAKING_CHANGES.md
@@ -2,6 +2,77 @@
# Version 8.0.0
+## Change
+
+The JavascriptEngine::callFunctionObject() function has been removed.
+
+**Possible Issues**
+
+Projects that used the removed function will fail to compile.
+
+**Workaround**
+
+Use the JSObjectCursor::invokeMethod() function to call functions beyond the
+root scope.
+
+**Rationale**
+
+The JavascriptEngine's underlying implementation has been changed, and the
+DynamicObject type is no longer used for the internal implementation of the
+engine. The JSObjectCursor class provides a way to navigate the Javascript
+object graph without depending on the type of the engine's internal
+implementation.
+
+
+## Change
+
+The JavascriptEngine::getRootObjectProperties() function returns its result by
+value instead of const reference.
+
+**Possible Issues**
+
+Projects that captured the returned value by reference and depended on it being
+valid for more than the current function's scope may stop working correctly.
+
+**Workaround**
+
+If the return value is used beyond the calling function's scope it must be
+stored in a value.
+
+**Rationale**
+
+The JavascriptEngine's underlying implementation has been changed, and the
+NamedValueSet type is no longer used in its internal representation. Hence a new
+NamedValueSet object is created during the getRootObjectProperties() function
+call.
+
+
+## Change
+
+JavascriptEngine::evaluate() will now return a void variant if the passed in
+code successfully evaluates to void, and only return an undefined variant if
+an error occurred during evaluation. The previous implementation would return
+var::undefined() in both cases.
+
+**Possible Issues**
+
+Projects that depended on the returned value of JavascriptEngine::evaluate() to
+be undefined even during successful evaluation may fail to work correctly.
+
+**Workaround**
+
+Code paths that depend on an undefined variant to be returned should be checked
+if they aren't used exclusively to determine evaluation failure. In failed
+cases the JavascriptEngine::evaluate() function will continue to return
+var::undefined().
+
+**Rationale**
+
+When a Javascript expression successfully evaluates to void, and when it fails
+evaluation due to timeout or syntax errors are distinctly different situations
+and this should be reflected on the value returned.
+
+
## Change
The `WebBrowserComponent::pageAboutToLoad()` function on Android now only
@@ -34,6 +105,7 @@ any visible effect, like there was on the other platforms. The fine grained per
resource control was not possible on other platforms. This change makes the
Android implementation more consistent with the other platforms.
+
## Change
The minimum supported compilers and deployment targets have been updated, with
diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt
index 5ac4cfe8ec..8ea68e859f 100644
--- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt
+++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt
@@ -1047,6 +1047,17 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/files/juce_TemporaryFile.h"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.h"
+ "../../../../../modules/juce_core/javascript/choc/containers/choc_Value.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript_QuickJS.h"
+ "../../../../../modules/juce_core/javascript/choc/math/choc_MathHelpers.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_Assert.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_DisableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_ReenableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_FloatToString.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_JSON.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_StringUtilities.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_UTF8.h"
"../../../../../modules/juce_core/javascript/juce_Javascript.cpp"
"../../../../../modules/juce_core/javascript/juce_Javascript.h"
"../../../../../modules/juce_core/javascript/juce_JSON.cpp"
@@ -3163,6 +3174,17 @@ set_source_files_properties(
"../../../../../modules/juce_core/files/juce_TemporaryFile.h"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.h"
+ "../../../../../modules/juce_core/javascript/choc/containers/choc_Value.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript_QuickJS.h"
+ "../../../../../modules/juce_core/javascript/choc/math/choc_MathHelpers.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_Assert.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_DisableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_ReenableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_FloatToString.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_JSON.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_StringUtilities.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_UTF8.h"
"../../../../../modules/juce_core/javascript/juce_Javascript.cpp"
"../../../../../modules/juce_core/javascript/juce_Javascript.h"
"../../../../../modules/juce_core/javascript/juce_JSON.cpp"
diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj
index 56bd871e63..a85d3018ad 100644
--- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj
+++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj
@@ -3408,6 +3408,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters
index bed4e708c3..9afe459309 100644
--- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters
+++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters
@@ -431,6 +431,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -5331,6 +5349,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
index 87546a8431..b7a4dffd91 100644
--- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
+++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
@@ -3408,6 +3408,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
index ab09f1c29a..9d97fe5147 100644
--- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
+++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
@@ -431,6 +431,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -5331,6 +5349,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
index 9aaf0ab602..e92f9e0f3a 100644
--- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
+++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
@@ -3408,6 +3408,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
index 5bd8867827..6aef77237b 100644
--- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
+++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
@@ -431,6 +431,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -5331,6 +5349,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/examples/Utilities/JavaScriptDemo.h b/examples/Utilities/JavaScriptDemo.h
index def4374068..56b888aa03 100644
--- a/examples/Utilities/JavaScriptDemo.h
+++ b/examples/Utilities/JavaScriptDemo.h
@@ -52,6 +52,28 @@
#include "../Assets/DemoUtilities.h"
+static constexpr const char javascriptSource[] = R"x(/*
+ Javascript! In this simple demo, the native
+ code provides an object called 'Demo' which
+ has a method 'print' that writes to the
+ console below...
+*/
+
+Demo.print ("Hello World in JUCE + Javascript!");
+Demo.print ("");
+
+function factorial (n)
+{
+ var total = 1;
+ while (n > 0)
+ total = total * n--;
+ return total;
+}
+
+for (var i = 1; i < 10; ++i)
+ Demo.print ("Factorial of " + i + " = " + factorial (i));
+)x";
+
//==============================================================================
class JavaScriptDemo final : public Component,
private CodeDocument::Listener,
@@ -75,28 +97,7 @@ public:
codeDocument.addListener (this);
- editor->loadContent (
- "/*\n"
- " Javascript! In this simple demo, the native\n"
- " code provides an object called \'Demo\' which\n"
- " has a method \'print\' that writes to the\n"
- " console below...\n"
- "*/\n"
- "\n"
- "Demo.print (\"Hello World in JUCE + Javascript!\");\n"
- "Demo.print (\"\");\n"
- "\n"
- "function factorial (n)\n"
- "{\n"
- " var total = 1;\n"
- " while (n > 0)\n"
- " total = total * n--;\n"
- " return total;\n"
- "}\n"
- "\n"
- "for (var i = 1; i < 10; ++i)\n"
- " Demo.print (\"Factorial of \" + i \n"
- " + \" = \" + factorial (i));\n");
+ editor->loadContent (javascriptSource);
setSize (600, 750);
}
diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
index 5854c58cf4..2c23c82cc9 100644
--- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
+++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
@@ -906,6 +906,17 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/files/juce_TemporaryFile.h"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.h"
+ "../../../../../modules/juce_core/javascript/choc/containers/choc_Value.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript_QuickJS.h"
+ "../../../../../modules/juce_core/javascript/choc/math/choc_MathHelpers.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_Assert.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_DisableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_ReenableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_FloatToString.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_JSON.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_StringUtilities.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_UTF8.h"
"../../../../../modules/juce_core/javascript/juce_Javascript.cpp"
"../../../../../modules/juce_core/javascript/juce_Javascript.h"
"../../../../../modules/juce_core/javascript/juce_JSON.cpp"
@@ -2704,6 +2715,17 @@ set_source_files_properties(
"../../../../../modules/juce_core/files/juce_TemporaryFile.h"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.h"
+ "../../../../../modules/juce_core/javascript/choc/containers/choc_Value.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript_QuickJS.h"
+ "../../../../../modules/juce_core/javascript/choc/math/choc_MathHelpers.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_Assert.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_DisableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_ReenableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_FloatToString.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_JSON.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_StringUtilities.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_UTF8.h"
"../../../../../modules/juce_core/javascript/juce_Javascript.cpp"
"../../../../../modules/juce_core/javascript/juce_Javascript.h"
"../../../../../modules/juce_core/javascript/juce_JSON.cpp"
diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
index b43ce54201..95cac1cb46 100644
--- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
+++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
@@ -2932,6 +2932,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
index 99437145e5..1358177bd5 100644
--- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
+++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
@@ -374,6 +374,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -4545,6 +4563,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
index 5afbc63479..3b0ca25302 100644
--- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
+++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
@@ -939,6 +939,17 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/files/juce_TemporaryFile.h"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.h"
+ "../../../../../modules/juce_core/javascript/choc/containers/choc_Value.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript_QuickJS.h"
+ "../../../../../modules/juce_core/javascript/choc/math/choc_MathHelpers.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_Assert.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_DisableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_ReenableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_FloatToString.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_JSON.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_StringUtilities.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_UTF8.h"
"../../../../../modules/juce_core/javascript/juce_Javascript.cpp"
"../../../../../modules/juce_core/javascript/juce_Javascript.h"
"../../../../../modules/juce_core/javascript/juce_JSON.cpp"
@@ -2890,6 +2901,17 @@ set_source_files_properties(
"../../../../../modules/juce_core/files/juce_TemporaryFile.h"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.h"
+ "../../../../../modules/juce_core/javascript/choc/containers/choc_Value.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript_QuickJS.h"
+ "../../../../../modules/juce_core/javascript/choc/math/choc_MathHelpers.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_Assert.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_DisableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_ReenableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_FloatToString.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_JSON.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_StringUtilities.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_UTF8.h"
"../../../../../modules/juce_core/javascript/juce_Javascript.cpp"
"../../../../../modules/juce_core/javascript/juce_Javascript.h"
"../../../../../modules/juce_core/javascript/juce_JSON.cpp"
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj
index 3b62176222..927e6f4912 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj
+++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj
@@ -3112,6 +3112,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters
index ef6005f60b..a88542a744 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters
+++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters
@@ -383,6 +383,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -4821,6 +4839,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
index b7fdf0a2fa..a4ad1820a0 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
+++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
@@ -3112,6 +3112,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
index 8f917b497d..1034f376ac 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
+++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
@@ -383,6 +383,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -4821,6 +4839,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
index 79583b920f..7c7c36d24e 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
+++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
@@ -3112,6 +3112,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
index c59ccfb021..5defba49a7 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
+++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
@@ -383,6 +383,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -4821,6 +4839,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj
index a5a99dcf64..420ae0b099 100644
--- a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj
+++ b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj
@@ -536,6 +536,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters
index a4fa26def5..41770e8b3c 100644
--- a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters
+++ b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters
@@ -17,6 +17,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -573,6 +591,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
index 1e319523c0..f3b5b6614d 100644
--- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
+++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
@@ -910,6 +910,17 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/files/juce_TemporaryFile.h"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.h"
+ "../../../../../modules/juce_core/javascript/choc/containers/choc_Value.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript_QuickJS.h"
+ "../../../../../modules/juce_core/javascript/choc/math/choc_MathHelpers.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_Assert.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_DisableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_ReenableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_FloatToString.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_JSON.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_StringUtilities.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_UTF8.h"
"../../../../../modules/juce_core/javascript/juce_Javascript.cpp"
"../../../../../modules/juce_core/javascript/juce_Javascript.h"
"../../../../../modules/juce_core/javascript/juce_JSON.cpp"
@@ -2788,6 +2799,17 @@ set_source_files_properties(
"../../../../../modules/juce_core/files/juce_TemporaryFile.h"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.cpp"
"../../../../../modules/juce_core/files/juce_WildcardFileFilter.h"
+ "../../../../../modules/juce_core/javascript/choc/containers/choc_Value.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript.h"
+ "../../../../../modules/juce_core/javascript/choc/javascript/choc_javascript_QuickJS.h"
+ "../../../../../modules/juce_core/javascript/choc/math/choc_MathHelpers.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_Assert.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_DisableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/platform/choc_ReenableAllWarnings.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_FloatToString.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_JSON.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_StringUtilities.h"
+ "../../../../../modules/juce_core/javascript/choc/text/choc_UTF8.h"
"../../../../../modules/juce_core/javascript/juce_Javascript.cpp"
"../../../../../modules/juce_core/javascript/juce_Javascript.h"
"../../../../../modules/juce_core/javascript/juce_JSON.cpp"
diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
index f45470e92d..5abd183e64 100644
--- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
+++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
@@ -3023,6 +3023,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
index 10211f5c14..31a3dec7d2 100644
--- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
+++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
@@ -374,6 +374,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -4686,6 +4704,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj
index 7f0bc7daaa..26755cc5c0 100644
--- a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj
+++ b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj
@@ -1840,6 +1840,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters
index eb111973b6..280b0872d6 100644
--- a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters
+++ b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters
@@ -98,6 +98,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -2664,6 +2682,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
index d95c784e46..d8d1dc4eda 100644
--- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
+++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
@@ -1840,6 +1840,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
index 4c027a6749..7e43f4c8b9 100644
--- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
+++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
@@ -98,6 +98,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -2664,6 +2682,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
index 46349d6895..0bed06da08 100644
--- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
+++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
@@ -1840,6 +1840,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
index 93e78711c8..aa86ca2ce6 100644
--- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
+++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
@@ -98,6 +98,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -2664,6 +2682,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj
index ad13bd327d..2e2ba4b0ef 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj
+++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj
@@ -3208,6 +3208,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters
index da2ac2662d..347903b0e1 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters
+++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters
@@ -383,6 +383,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -4935,6 +4953,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
index 7e10c32d81..d59d5f1320 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
+++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
@@ -3208,6 +3208,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
index 267af7544d..6d588522bd 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
+++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
@@ -383,6 +383,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -4935,6 +4953,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
index d79d393698..cf64a33188 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
+++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
@@ -3208,6 +3208,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
index 9bdc83fe2a..d162a01d6b 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
+++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
@@ -383,6 +383,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -4935,6 +4953,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj
index d1e05c512b..c1ca7a9644 100644
--- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj
+++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj
@@ -2999,6 +2999,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters
index 4ad221d138..073a6fec31 100644
--- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters
+++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters
@@ -368,6 +368,24 @@
{7868764A-6572-381A-906C-9C26792A4C29}
+
+ {259B70B2-0C68-1990-EC86-42DAA564D388}
+
+
+ {19C3DF40-ABE4-49F7-CDD2-7A592EA01F73}
+
+
+ {20DE6E65-B828-EB00-17F7-541D368DFA9B}
+
+
+ {5CCB85C1-6052-8F8C-FCA7-E34D5514A0EE}
+
+
+ {375615B1-7B81-BB18-920B-926E88A78F9A}
+
+
+ {17CA846A-C621-9676-4FBD-8B04DBAA4488}
+ {03678508-A517-48BB-FB4A-485628C34E08}
@@ -4653,6 +4671,39 @@
JUCE Modules\juce_core\files
+
+ JUCE Modules\juce_core\javascript\choc\containers
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\javascript
+
+
+ JUCE Modules\juce_core\javascript\choc\math
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\platform
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+
+
+ JUCE Modules\juce_core\javascript\choc\text
+ JUCE Modules\juce_core\javascript
diff --git a/modules/juce_core/javascript/choc/containers/choc_Value.h b/modules/juce_core/javascript/choc/containers/choc_Value.h
new file mode 100644
index 0000000000..ea8d97fd2d
--- /dev/null
+++ b/modules/juce_core/javascript/choc/containers/choc_Value.h
@@ -0,0 +1,3240 @@
+//
+// ██████ ██ ██ ██████ ██████
+// ██ ██ ██ ██ ██ ██ ** Classy Header-Only Classes **
+// ██ ███████ ██ ██ ██
+// ██ ██ ██ ██ ██ ██ https://github.com/Tracktion/choc
+// ██████ ██ ██ ██████ ██████
+//
+// CHOC is (C)2022 Tracktion Corporation, and is offered under the terms of the ISC license:
+//
+// Permission to use, copy, modify, and/or distribute this software for any purpose with or
+// without fee is hereby granted, provided that the above copyright notice and this permission
+// notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef CHOC_VALUE_POOL_HEADER_INCLUDED
+#define CHOC_VALUE_POOL_HEADER_INCLUDED
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../platform/choc_Assert.h"
+
+namespace choc::value
+{
+
+class Value;
+class ValueView;
+class StringDictionary;
+struct MemberNameAndType;
+struct MemberNameAndValue;
+struct ElementTypeAndOffset;
+
+// This macro lets you override the primitive type that will be used for
+// encoding bool elements in a choc::value::ValueView. This setting makes
+// no difference to the way the serialisation is done, but affects the way
+// elements are packed in memory in a live value object. By default this uses
+// a uint32_t for bools, so that all data elements are 4-byte aligned, but you
+// could change it to a uint8_t if you want to pack the data more tightly at
+// the expense of aligned read/write access.
+#ifdef CHOC_VALUE_BOOL_STORAGE_TYPE
+ using BoolStorageType = CHOC_VALUE_BOOL_STORAGE_TYPE;
+#else
+ using BoolStorageType = uint32_t;
+#endif
+
+//==============================================================================
+/// An exception object which is thrown by the Type, Value and ValueView classes when various
+/// runtime checks fail.
+/// @see Type, Value, ValueView
+struct Error : public std::exception
+{
+ Error (const char* desc) : description (desc) {}
+
+ const char* what() const noexcept override { return description; }
+ const char* description;
+};
+
+
+/// Throws an error exception.
+/// Note that the message string is taken as a raw pointer and not copied, so must be a string literal.
+/// This is used by the Type, Value and ValueView classes.
+/// @see Type, Value, ValueView
+[[noreturn]] static void throwError (const char* errorMessage) { throw Error (errorMessage); }
+
+/// Throws an Error with the given message if the condition argument is false.
+/// Note that the message string is taken as a raw pointer and not copied, so must be a string literal.
+/// This is used by the Type, Value and ValueView classes.
+static void check (bool condition, const char* errorMessage) { if (! condition) throwError (errorMessage); }
+
+/// Used by some deserialisation methods in Type, Value and StringDictionary
+struct InputData
+{
+ const uint8_t* start;
+ const uint8_t* end;
+};
+
+/// This helper class holds a chunk of data that is a serialised Value or ValueView, and has
+/// a handy method to turn it back into a Value object.
+struct SerialisedData
+{
+ std::vector data;
+
+ Value deserialise() const;
+ InputData getInputData() const;
+ void write (const void*, size_t);
+};
+
+/** A custom allocator class which can be used to replace the normal heap allocator
+ for a Type object. This is mainly useful if you need to create and manipulate Type
+ and Value objects on a realtime thread and need a fast pool allocator.
+ If you pass a custom allocator to the Type class, you must make sure that its lifetime
+ is greater than that of the Types that are created (both directly and possibly indirectly
+ as nested sub-types).
+*/
+struct Allocator
+{
+ virtual ~Allocator() = default;
+ virtual void* allocate (size_t size) = 0;
+ virtual void* resizeIfPossible (void*, size_t requestedSize) = 0;
+ virtual void free (void*) noexcept = 0;
+};
+
+//==============================================================================
+/** */
+template
+struct FixedPoolAllocator : public Allocator
+{
+ FixedPoolAllocator() = default;
+ ~FixedPoolAllocator() override = default;
+
+ void reset() noexcept { position = 0; }
+ void* allocate (size_t size) override;
+ void* resizeIfPossible (void* data, size_t requiredSize) override;
+ void free (void*) noexcept override {}
+
+private:
+ size_t position = 0, lastAllocationPosition = 0;
+ char pool[totalSize];
+};
+
+//==============================================================================
+/** A type class that can represent primitives, vectors, strings, arrays and objects.
+
+ A Type can represent:
+ - A primitive int32 or int64
+ - A primitive float or double
+ - A primitive bool
+ - A vector of primitives
+ - A string
+ - An array of other Values
+ - An object, which has a class name and a set of named members, each holding another Value.
+
+ The Type class attempts to be small and allocation-free for simple types like primitives, vectors and
+ arrays of vectors, but will use heap storage when given something more complex to represent.
+
+ A Type can also be serialised and deserialised to a packed format.
+
+ @see Value, ValueView
+*/
+class Type final
+{
+public:
+ Type() = default;
+ Type (Type&&);
+ Type (const Type&);
+ Type (Allocator*, const Type&); ///< Constructs a copy of another type, using a custom allocator (which may be nullptr).
+ Type& operator= (Type&&);
+ Type& operator= (const Type&);
+ ~Type() noexcept;
+
+ bool isVoid() const noexcept { return isType (MainType::void_); }
+ bool isInt32() const noexcept { return isType (MainType::int32); }
+ bool isInt64() const noexcept { return isType (MainType::int64); }
+ bool isInt() const noexcept { return isType (MainType::int32, MainType::int64); }
+ bool isFloat32() const noexcept { return isType (MainType::float32); }
+ bool isFloat64() const noexcept { return isType (MainType::float64); }
+ bool isFloat() const noexcept { return isType (MainType::float32, MainType::float64); }
+ bool isBool() const noexcept { return isType (MainType::boolean); }
+ bool isPrimitive() const noexcept { return isType (MainType::int32, MainType::int64, MainType::float32, MainType::float64, MainType::boolean); }
+ bool isObject() const noexcept { return isType (MainType::object); }
+ bool isString() const noexcept { return isType (MainType::string); }
+ bool isVector() const noexcept { return isType (MainType::vector); }
+ bool isArray() const noexcept { return isType (MainType::primitiveArray, MainType::complexArray); }
+ bool isUniformArray() const; ///< A uniform array is one where every element has the same type.
+ bool isArrayOfVectors() const;
+ bool isVectorSize1() const;
+
+ /// Returns true if the type is the same as the provided template type (which must be a primitive)
+ template bool isPrimitiveType() const noexcept;
+
+ /// Returns the number of elements in an array, vector or object. Throws an Error if the type is void.
+ uint32_t getNumElements() const;
+
+ /// If the type is an array or vector with a uniform element type, this returns it; if not, it throws an Error.
+ Type getElementType() const;
+
+ /// Returns the type of a given element in this type if it's an array. If the type isn't an array or the index is
+ /// out of bounds, it will throw an Error.
+ Type getArrayElementType (uint32_t index) const;
+
+ /// For a vector or uniform array type, this allows the number of elements to be directly mutated.
+ /// For any other type, this will throw an Error exception.
+ void modifyNumElements (uint32_t newNumElements);
+
+ /// Returns the name and type of one of the members if this type is an object; if not, or the index is out
+ /// of range, then this will throw an Error exception.
+ const MemberNameAndType& getObjectMember (uint32_t index) const;
+
+ /// If this is an object, this returns the index of the member with a given name. If the name isn't found, it
+ /// will return -1, and if the type isn't an object, it will throw an Error exception.
+ int getObjectMemberIndex (std::string_view name) const;
+
+ /// Returns the class-name of this type if it's an object, or throws an Error if it's not.
+ std::string_view getObjectClassName() const;
+
+ /// Returns true if this is an object with the given class-name.
+ bool isObjectWithClassName (std::string_view name) const;
+
+ bool operator== (const Type&) const;
+ bool operator!= (const Type&) const;
+
+ //==============================================================================
+ static Type createVoid() { return Type (MainType::void_); }
+ static Type createInt32() { return Type (MainType::int32); }
+ static Type createInt64() { return Type (MainType::int64); }
+ static Type createFloat32() { return Type (MainType::float32); }
+ static Type createFloat64() { return Type (MainType::float64); }
+ static Type createBool() { return Type (MainType::boolean); }
+ static Type createString() { return Type (MainType::string); }
+
+ /// Creates a type based on the given template type.
+ template
+ static Type createPrimitive();
+
+ //==============================================================================
+ /// Creates a vector type based on the given template type and size.
+ template
+ static Type createVector (uint32_t numElements);
+
+ static Type createVectorInt32 (uint32_t numElements) { return Type (MainType::int32, numElements); }
+ static Type createVectorInt64 (uint32_t numElements) { return Type (MainType::int64, numElements); }
+ static Type createVectorFloat32 (uint32_t numElements) { return Type (MainType::float32, numElements); }
+ static Type createVectorFloat64 (uint32_t numElements) { return Type (MainType::float64, numElements); }
+ static Type createVectorBool (uint32_t numElements) { return Type (MainType::boolean, numElements); }
+
+ //==============================================================================
+ /// Creates a type representing an empty array. Element types can be appended with addArrayElements().
+ static Type createEmptyArray();
+
+ /// Creates a type representing an array containing a set of elements of a fixed type.
+ static Type createArray (Type elementType, uint32_t numElements);
+
+ /// Creates a type representing an array of primitives based on the templated type.
+ template
+ static Type createArray (uint32_t numArrayElements);
+
+ /// Creates a type representing an array of vectors based on the templated type.
+ template
+ static Type createArrayOfVectors (uint32_t numArrayElements, uint32_t numVectorElements);
+
+ /// Appends a group of array elements with the given to this type's definition.
+ /// This will throw an Error if this isn't possible for various reasons.
+ void addArrayElements (Type elementType, uint32_t numElements);
+
+ //==============================================================================
+ /// Returns a type representing an empty object, with the given class name.
+ static Type createObject (std::string_view className, Allocator* allocator = nullptr);
+
+ /// Appends a member to an object type, with the given name and type. This will throw an Error if
+ /// this isn't possible for some reason.
+ void addObjectMember (std::string_view memberName, Type memberType);
+
+ //==============================================================================
+ /// Returns the size in bytes needed to store a value of this type.
+ size_t getValueDataSize() const;
+
+ /// Returns true if this type, or any of its sub-types are a string.
+ bool usesStrings() const;
+
+ /// Returns the type and packed-data position of one of this type's sub-elements.
+ ElementTypeAndOffset getElementTypeAndOffset (uint32_t index) const;
+
+ //==============================================================================
+ /** Stores a representation of this type in a packed data format.
+ It can later be reloaded with deserialise(). The OutputStream template can
+ be any object which has a method write (const void*, size_t)
+
+ The data format is simple:
+ Primitives: type (1 byte)
+ Vectors: type (1 byte), num elements (packed int), primitive type (1 byte)
+ Array: type (1 byte), num groups (packed int), [num repetitions (packed int), element type (type)]*
+ Object: type (1 byte), num members (packed int), name (null-term string), [member type (type), member name (null-term string)]*
+
+ Packed ints are stored as a sequence of bytes in little-endian order, where each byte contains
+ 7 bits of data + the top bit is set if another byte follows it.
+
+ @see deserialise
+ */
+ template
+ void serialise (OutputStream&) const;
+
+ /// Recreates a type from a serialised version that was created by the serialise() method.
+ /// Any errors while reading the data will cause an Error exception to be thrown.
+ /// The InputData object will be left pointing to any remaining data after the type has been read.
+ /// @see serialise
+ static Type deserialise (InputData&, Allocator* allocator = nullptr);
+
+ /// Returns a representation of this type in the form of a Value. @see fromValue
+ Value toValue() const;
+
+ /// Parses a Value which was created by toValue(), converting it back into a Type object.
+ static Type fromValue (const ValueView&);
+
+ /// Returns a human-interpretable description of this type, useful for debugging.
+ std::string getDescription() const;
+
+ /// Returns a compact string to uniquely describe this type's layout.
+ /// The signature includes information about any sub-types, e.g object member types, array
+ /// element types and array sizes. If includeNames is true, it also embeds the names of objects
+ /// and members, but if false it will ingore names and represent the "duck" type.
+ std::string getSignature (bool includeNames) const;
+
+private:
+ //==============================================================================
+ enum class MainType : uint8_t
+ {
+ void_ = 0,
+ int32 = 0x00 + sizeof (int32_t),
+ int64 = 0x00 + sizeof (int64_t),
+ float32 = 0x10 + sizeof (float),
+ float64 = 0x10 + sizeof (double),
+ boolean = 0x30 + sizeof (BoolStorageType),
+ string = 0x40 + sizeof (uint32_t),
+ vector = 0x50,
+ primitiveArray = 0x60,
+ object = 0x80, // these two must have the top bit set to make it quick
+ complexArray = 0x90 // to decide whether the content references a heap object
+ };
+
+ static constexpr uint32_t maxNumVectorElements = 256;
+ static constexpr uint32_t maxNumArrayElements = 1024 * 1024;
+
+ static constexpr uint32_t getPrimitiveSize (MainType t) { return static_cast (t) & 15; }
+
+ friend class ValueView;
+ friend class Value;
+ struct SerialisationHelpers;
+ struct ComplexArray;
+ struct Object;
+ template struct AllocatedVector;
+
+ struct Vector
+ {
+ MainType elementType;
+ uint32_t numElements;
+
+ size_t getElementSize() const;
+ size_t getValueDataSize() const;
+ ElementTypeAndOffset getElementInfo (uint32_t) const;
+ ElementTypeAndOffset getElementRangeInfo (uint32_t start, uint32_t length) const;
+ bool operator== (const Vector&) const;
+ };
+
+ struct PrimitiveArray
+ {
+ MainType elementType;
+ uint32_t numElements, numVectorElements;
+
+ Type getElementType() const;
+ size_t getElementSize() const;
+ size_t getValueDataSize() const;
+ ElementTypeAndOffset getElementInfo (uint32_t) const;
+ ElementTypeAndOffset getElementRangeInfo (uint32_t start, uint32_t length) const;
+ bool operator== (const PrimitiveArray&) const;
+ };
+
+ union Content
+ {
+ Object* object;
+ ComplexArray* complexArray;
+ Vector vector;
+ PrimitiveArray primitiveArray;
+ };
+
+ MainType mainType = MainType::void_;
+ Content content = {};
+ Allocator* allocator = nullptr;
+
+ template bool isType (Types... types) const noexcept { return ((mainType == types) || ...); }
+ template static constexpr MainType selectMainType();
+
+ explicit Type (MainType);
+ Type (MainType, Content, Allocator*);
+ Type (MainType vectorElementType, uint32_t);
+ void allocateCopy (const Type&);
+ void deleteAllocatedObjects() noexcept;
+ ElementTypeAndOffset getElementRangeInfo (uint32_t start, uint32_t length) const;
+ template void visitStringHandles (size_t, const Visitor&) const;
+ static Type createArray (Type elementType, uint32_t numElements, Allocator*);
+};
+
+//==============================================================================
+/** This holds the type and location of a sub-element of a Type.
+ @see Type::getElementTypeAndOffset()
+*/
+struct ElementTypeAndOffset
+{
+ Type elementType;
+ size_t offset; ///< The byte position within its parent value of the data representing this element
+};
+
+//==============================================================================
+/** A simple dictionary base-class for mapping strings onto integer handles.
+ This is needed by the Value and ValueView classes.
+ @see Value, ValueView
+*/
+class StringDictionary
+{
+public:
+ StringDictionary() = default;
+ virtual ~StringDictionary() = default;
+
+ struct Handle
+ {
+ uint32_t handle = 0;
+
+ bool operator== (Handle h) const { return handle == h.handle; }
+ bool operator!= (Handle h) const { return handle != h.handle; }
+ bool operator< (Handle h) const { return handle < h.handle; }
+ };
+
+ /// Finds or creates a handle for a string.
+ virtual Handle getHandleForString (std::string_view stringToAdd) = 0;
+
+ /// Fetches the string for a given handle. If the handle isn't found,
+ /// the implementation may throw an error.
+ virtual std::string_view getStringForHandle (Handle handle) const = 0;
+};
+
+
+//==============================================================================
+/** A simple implementation of StringDictionary.
+ This should have good performance for typical-sized dictionaries.
+ Adding new strings will require O(n) time where n = dictionary size, but
+ retrieving the string for a handle is fast with O(1).
+*/
+struct SimpleStringDictionary : public StringDictionary
+{
+ Handle getHandleForString (std::string_view) override;
+ std::string_view getStringForHandle (Handle handle) const override;
+
+ void clear();
+
+ /// The strings are stored in a single chunk, which can be saved and
+ /// reloaded if necessary.
+ std::vector strings;
+};
+
+//==============================================================================
+/**
+ Represents a view onto an object which can represent various types of primitive,
+ array and object types.
+
+ The ValueView and Value classes differ in that ValueView does not own the data that it
+ points to, but Value does. A ValueView should be used as a temporary wrapper around some
+ data whose lifetime can be trusted to outlive the ValueView object. As a rule-of-thumb, you
+ should treat Value and Valueview in the same way as std::string and std::string_view, so
+ a ValueView makes a great type for a function parameter, but probably shouldn't be used
+ as a function return type unless you really know what you're doing.
+
+ The purpose of these classes is to allow manipulation of complex, dynamically-typed objects
+ where the data holding a value is stored in a contiguous, packed, well-specified data
+ format, so that it can be manipulated directly as raw memory when necessary. The ValueView
+ is a lightweight wrapper around a type and a pointer to the raw data containing a value of that
+ type. The Value class provides the same interface, but also owns the storage needed, and can
+ return a ValueView of itself.
+
+ @see Type, Value, choc::json::toString()
+*/
+class ValueView final
+{
+public:
+ ValueView(); ///< Creates an empty value with a type of 'void'.
+ ValueView (Type&&, void* data, StringDictionary*); ///< Creates a value using the given type and raw block of data.
+ ValueView (const Type&, void* data, StringDictionary*); ///< Creates a value using the given type and raw block of data.
+
+ ValueView (const ValueView&) = default;
+ ValueView& operator= (const ValueView&) = default;
+ ValueView& operator= (ValueView&&) = default;
+
+ //==============================================================================
+ const Type& getType() const { return type; }
+ Type& getMutableType() { return type; }
+
+ bool isVoid() const noexcept { return type.isVoid(); }
+ bool isInt32() const noexcept { return type.isInt32(); }
+ bool isInt64() const noexcept { return type.isInt64(); }
+ bool isInt() const noexcept { return type.isInt(); }
+ bool isFloat32() const noexcept { return type.isFloat32(); }
+ bool isFloat64() const noexcept { return type.isFloat64(); }
+ bool isFloat() const noexcept { return type.isFloat(); }
+ bool isBool() const noexcept { return type.isBool(); }
+ bool isPrimitive() const noexcept { return type.isPrimitive(); }
+ bool isObject() const noexcept { return type.isObject(); }
+ bool isString() const noexcept { return type.isString(); }
+ bool isVector() const noexcept { return type.isVector(); }
+ bool isArray() const noexcept { return type.isArray(); }
+
+ //==============================================================================
+ int32_t getInt32() const; ///< Retrieves the value if this is an int32, otherwise throws an Error exception.
+ int64_t getInt64() const; ///< Retrieves the value if this is an int64, otherwise throws an Error exception.
+ float getFloat32() const; ///< Retrieves the value if this is a float, otherwise throws an Error exception.
+ double getFloat64() const; ///< Retrieves the value if this is a double, otherwise throws an Error exception.
+ bool getBool() const; ///< Retrieves the value if this is a bool, otherwise throws an Error exception.
+ std::string_view getString() const; ///< Retrieves the value if this is a string, otherwise throws an Error exception.
+ StringDictionary::Handle getStringHandle() const; ///< Retrieves the value if this is a string handle, otherwise throws an Error exception.
+
+ explicit operator int32_t() const { return getInt32(); } ///< If the object is not an int32, this will throw an Error.
+ explicit operator int64_t() const { return getInt64(); } ///< If the object is not an int64, this will throw an Error.
+ explicit operator float() const { return getFloat32(); } ///< If the object is not a float, this will throw an Error.
+ explicit operator double() const { return getFloat64(); } ///< If the object is not a double, this will throw an Error.
+ explicit operator bool() const { return getBool(); } ///< If the object is not a bool, this will throw an Error.
+ explicit operator std::string_view() const { return getString(); } ///< If the object is not a string, this will throw an Error.
+
+ /// Attempts to cast this value to the given primitive target type. If the type is void or something that
+ /// can't be cast, it will throw an exception. This will do some minor casting, such as ints to doubles,
+ /// but won't attempt do any kind of string to number conversions.
+ template TargetType get() const;
+
+ /// Attempts to get this value as the given target type, but if this isn't possible,
+ /// returns the default value provided instead of throwing an Error.
+ template TargetType getWithDefault (TargetType defaultValue) const;
+
+ /// A handy way to convert this value as a string where possible, or to return an empty
+ /// string (without throwing any errors) if not possible. The function is basically the
+ /// same as calling getWithDefault ({})
+ std::string toString() const;
+
+ /// Attempts to write a new value to the memory pointed to by this view, as long as the type
+ /// provided exactly matches the value's type.
+ template void set (PrimitiveType newValue);
+
+ /// Resets this value to a 'zero' state. Note that for arrays, this won't change the size
+ /// of the array, it just sets all the existing elements to zero.
+ void setToZero();
+
+ //==============================================================================
+ /// If this object is a vector, array or object, this returns the number of items it contains; otherwise
+ /// it will throw an Error exception.
+ uint32_t size() const;
+
+ /// If this object is an array or vector, and the index is valid, this returns one of its elements.
+ /// Throws an error exception if the object is not a vector or the index is out of range.
+ ValueView operator[] (int index) const;
+
+ /// If this object is an array or vector, and the index is valid, this returns one of its elements.
+ /// Throws an error exception if the object is not a vector or the index is out of range.
+ ValueView operator[] (uint32_t index) const;
+
+ /// If this object is an array or vector, and the index and length do not exceed its bounds, this
+ /// will return a view onto a range of its elements.
+ /// Throws an error exception if the object is not a vector or the range is invalid.
+ ValueView getElementRange (uint32_t startIndex, uint32_t length) const;
+
+ //==============================================================================
+ struct Iterator;
+ struct EndIterator {};
+
+ /// Iterating a Value is only valid for an array, vector or object.
+ Iterator begin() const;
+ EndIterator end() const { return {}; }
+
+ //==============================================================================
+ /// Returns the class name of this object.
+ /// This will throw an error if the value is not an object.
+ std::string_view getObjectClassName() const;
+
+ /// Returns true if this is an object with the given class-name.
+ bool isObjectWithClassName (std::string_view name) const;
+
+ /// Returns the name and value of a member by index.
+ /// This will throw an error if the value is not an object of if the index is out of range. (Use
+ /// size() to find out how many members there are). To get a named value from an object, you can
+ /// use operator[].
+ /// @see size
+ MemberNameAndValue getObjectMemberAt (uint32_t index) const;
+
+ /// Returns the value of a named member, or a void value if no such member exists.
+ /// This will throw an error if the value is not an object.
+ ValueView operator[] (std::string_view name) const;
+
+ /// Returns the value of a named member, or a void value if no such member exists.
+ /// This will throw an error if the value is not an object.
+ ValueView operator[] (const char* name) const;
+
+ /// Returns true if this is an object and contains the given member name.
+ bool hasObjectMember (std::string_view name) const;
+
+ /// Calls a functor on each member in an object.
+ /// The functor must take two parameters of type (string_view name, const ValueView& value).
+ template
+ void visitObjectMembers (Visitor&&) const;
+
+ //==============================================================================
+ /// Performs a comparison between two values, where only a bit-for-bit match is
+ /// considered to be true.
+ bool operator== (const ValueView&) const;
+ /// Performs a comparison between two values, where only a bit-for-bit match is
+ /// considered to be true.
+ bool operator!= (const ValueView&) const;
+
+ //==============================================================================
+ /// Gets a pointer to the string dictionary that the view is using, or nullptr
+ /// if it doesn't have one.
+ StringDictionary* getDictionary() const { return stringDictionary; }
+
+ /// Allows you to change the string dictionary which this view is using.
+ /// Changing the dictionary will visit all the strings inside the object,
+ /// remapping old handles into new ones from the new dictionary.
+ void setDictionary (StringDictionary* newDictionary);
+
+ /// Gets a pointer to the memory that this view is using for its content.
+ void* getRawData() { return data; }
+ /// Gets a pointer to the memory that this view is using for its content.
+ const void* getRawData() const { return data; }
+ /// Allows you to directly modify the internal pointer to the data that this view is
+ /// using. Obviously this should only be used if you really know what you're doing!
+ void setRawData (void* newAddress) { data = static_cast (newAddress); }
+
+ //==============================================================================
+ /// Stores a complete representation of this value and its type in a packed data format.
+ /// It can later be reloaded with Value::deserialise() or ValueView::deserialise().
+ /// The OutputStream object can be any class which has a method write (const void*, size_t).
+ /// The data format is:
+ /// - The serialised Type data, as written by Type::serialise()
+ /// - The block of value data, which is a copy of getRawData(), the size being Type::getValueDataSize()
+ /// - If any strings are in the dictionary, this is followed by a packed int for the total size of
+ /// the remaining string block, then a sequence of null-terminated strings. String handles are
+ /// encoded as a byte offset into this table, where the first character of the first string = 1.
+ /// @see Value::deserialise, ValueView::deserialise
+ template
+ void serialise (OutputStream&) const;
+
+ /// Returns an object containing a serialised representation of this value. This is a helper
+ /// function to make it easier to call serialise() without needing to use your own output
+ /// stream class.
+ SerialisedData serialise() const;
+
+ /// Recreates a temporary ValueView from serialised data that was created by the
+ /// ValueView::serialise() method.
+ /// If a ValueView is successfully deserialised from the data, the handler functor will be
+ /// called with this (temporary!) ValueView as its argument.
+ /// Any errors while reading the data will cause an Error exception to be thrown.
+ /// The InputData object will be left pointing to any remaining data after the value has been read.
+ /// @see Value::serialise
+ template
+ static void deserialise (InputData&, Handler&& handleResult,
+ Allocator* allocator = nullptr);
+
+private:
+ //==============================================================================
+ friend class Value;
+
+ Type type;
+ uint8_t* data = nullptr;
+ StringDictionary* stringDictionary = nullptr;
+
+ ValueView (StringDictionary&);
+ template TargetType readContentAs() const;
+ template TargetType castToType (TargetType*) const;
+ template void setUnchecked (PrimitiveType);
+ void updateStringHandles (StringDictionary&, StringDictionary&);
+
+ ValueView operator[] (const void*) const = delete;
+ ValueView operator[] (bool) const = delete;
+};
+
+
+//==============================================================================
+/** Represents the name and type of a member in an object.
+ @see Type
+*/
+struct MemberNameAndType
+{
+ std::string_view name;
+ Type type;
+};
+
+/** Represents the name and value of a member in an object.
+ @see Value, ValueView
+*/
+struct MemberNameAndValue
+{
+ const char* name;
+ ValueView value;
+};
+
+
+//==============================================================================
+/**
+ Stores a value of any type that the Type class can represent.
+
+ A Value class can be treated as a by-value class, and manages all the storage needed to
+ represent a ValueView object.
+
+ The ValueView and Value classes differ in that ValueView does not own the data that it
+ points to, but Value does. A ValueView should be used as a temporary wrapper around some
+ data whose lifetime can be trusted to outlive the ValueView object.
+
+ The purpose of these classes is to allow manipulation of complex, dynamically-typed objects
+ where the data holding a value is stored in a contiguous, packed, well-specified data
+ format, so that it can be manipulated directly as raw memory when necessary. The ValueView
+ is a lightweight wrapper around a type and a pointer to the raw data containing a value of that
+ type. The Value class provides the same interface, but also owns the storage needed, and can
+ return a ValueView of itself.
+
+ The Value class is versatile enough, and close enough to JSON's architecture that it can be
+ parsed and printed as JSON (though storing a Value as JSON will be a slightly lossy operation
+ as JSON has fewer types).
+
+ @see ValueView, Type, choc::json::parse(), choc::json::toString()
+*/
+class Value final
+{
+public:
+ /// Creates an empty value with a type of 'void'.
+ Value();
+
+ Value (Value&&);
+ Value (const Value&);
+ Value& operator= (Value&&);
+ Value& operator= (const Value&);
+
+ /// Creates a zero-initialised value with the given type.
+ explicit Value (const Type&);
+
+ /// Creates a zero-initialised value with the given type.
+ explicit Value (Type&&);
+
+ /// Creates a deep-copy of the given ValueView.
+ explicit Value (const ValueView&);
+
+ /// Creates a deep-copy of the given ValueView.
+ explicit Value (ValueView&&);
+
+ /// Creates a deep-copy of the given ValueView.
+ Value& operator= (const ValueView&);
+
+ explicit Value (int32_t);
+ explicit Value (int64_t);
+ explicit Value (float);
+ explicit Value (double);
+ explicit Value (bool);
+ explicit Value (std::string_view);
+ explicit Value (const char*);
+
+ //==============================================================================
+ /// Appends an element to this object, if it's an array. If not, then this will throw an Error exception.
+ template
+ void addArrayElement (ElementType);
+
+ /// Appends one or more members to an object, with the given names and values.
+ /// The value can be a supported primitive type, a string, or a Value or ValueView.
+ /// The function can take any number of name/value pairs.
+ /// This will throw an Error if this isn't possible for some reason (e.g. if the value isn't an object)
+ template
+ void addMember (std::string_view name, MemberType value, Others&&...);
+
+ /// Adds or changes an object member to a new value.
+ template
+ void setMember (std::string_view name, MemberType newValue);
+
+ //==============================================================================
+ bool isVoid() const { return value.isVoid(); }
+ bool isInt32() const { return value.isInt32(); }
+ bool isInt64() const { return value.isInt64(); }
+ bool isInt() const { return value.isInt(); }
+ bool isFloat32() const { return value.isFloat32(); }
+ bool isFloat64() const { return value.isFloat64(); }
+ bool isFloat() const { return value.isFloat(); }
+ bool isBool() const { return value.isBool(); }
+ bool isPrimitive() const { return value.isPrimitive(); }
+ bool isObject() const { return value.isObject(); }
+ bool isString() const { return value.isString(); }
+ bool isVector() const { return value.isVector(); }
+ bool isArray() const { return value.isArray(); }
+
+ //==============================================================================
+ int32_t getInt32() const { return value.getInt32(); } ///< Retrieves the value if this is an int32, otherwise throws an Error exception.
+ int64_t getInt64() const { return value.getInt64(); } ///< Retrieves the value if this is an int64, otherwise throws an Error exception.
+ float getFloat32() const { return value.getFloat32(); } ///< Retrieves the value if this is a float, otherwise throws an Error exception.
+ double getFloat64() const { return value.getFloat64(); } ///< Retrieves the value if this is a double, otherwise throws an Error exception.
+ bool getBool() const { return value.getBool(); } ///< Retrieves the value if this is a bool, otherwise throws an Error exception.
+ std::string_view getString() const { return value.getString(); } ///< Retrieves the value if this is a string, otherwise throws an Error exception.
+ StringDictionary::Handle getStringHandle() const { return value.getStringHandle(); } ///< Retrieves the value if this is a string handle, otherwise throws an Error exception.
+
+ explicit operator int32_t() const { return value.getInt32(); } ///< If the object is not an int32, this will throw an Error.
+ explicit operator int64_t() const { return value.getInt64(); } ///< If the object is not an int64, this will throw an Error.
+ explicit operator float() const { return value.getFloat32(); } ///< If the object is not a float, this will throw an Error.
+ explicit operator double() const { return value.getFloat64(); } ///< If the object is not a double, this will throw an Error.
+ explicit operator bool() const { return value.getBool(); } ///< If the object is not a bool, this will throw an Error.
+ explicit operator std::string_view() const { return value.getString(); } ///< If the object is not a string, this will throw an Error.
+
+ /// Attempts to cast this value to the given primitive target type. If the type is void or something that
+ /// can't be cast, it will throw an exception. This will do some minor casting, such as ints to doubles,
+ /// but won't attempt do any kind of string to number conversions.
+ template TargetType get() const;
+
+ /// Attempts to get this value as the given target type, but if this isn't possible,
+ /// returns the default value provided instead of throwing an Error.
+ template TargetType getWithDefault (TargetType defaultValue) const;
+
+ /// A handy way to convert this value as a string where possible, or to return an empty
+ /// string (without throwing any errors) if not possible. The function is basically the
+ /// same as calling getWithDefault ({})
+ std::string toString() const;
+
+ /// If this object is a vector, array or object, this returns the number of items it contains; otherwise
+ /// it will throw an Error exception.
+ uint32_t size() const { return value.size(); }
+
+ /// If this object is an array or vector, and the index is valid, this returns one of its elements.
+ /// Note that this returns a view of the parent Value, which will become invalid as soon as any
+ /// change is made to the parent Value.
+ /// Throws an error exception if the object is not a vector or the index is out of range.
+ ValueView operator[] (int index) const { return value[index]; }
+
+ /// If this object is an array or vector, and the index is valid, this returns one of its elements.
+ /// Note that this returns a view of the parent Value, which will become invalid as soon as any
+ /// change is made to the parent Value.
+ /// Throws an error exception if the object is not a vector or the index is out of range.
+ ValueView operator[] (uint32_t index) const { return value[index]; }
+
+ /// If this object is an array or vector, and the index and length do not exceed its bounds, this
+ /// will return a view onto a range of its elements.
+ /// Throws an error exception if the object is not a vector or the range is invalid.
+ ValueView getElementRange (uint32_t startIndex, uint32_t length) const { return value.getElementRange (startIndex, length); }
+
+ //==============================================================================
+ /// Performs a comparison between two values, where only a bit-for-bit match is
+ /// considered to be true.
+ bool operator== (const ValueView& other) const { return value == other; }
+
+ /// Performs a comparison between two values, where only a bit-for-bit match is
+ /// considered to be true.
+ bool operator!= (const ValueView& other) const { return value != other; }
+
+ //==============================================================================
+ /// Iterating a Value is only valid for an array, vector or object.
+ ValueView::Iterator begin() const;
+ ValueView::EndIterator end() const;
+
+ //==============================================================================
+ /// Returns the class name of this object.
+ /// This will throw an error if the value is not an object.
+ std::string_view getObjectClassName() const { return value.getObjectClassName(); }
+
+ /// Returns true if this is an object with the given class-name.
+ bool isObjectWithClassName (std::string_view name) const { return value.isObjectWithClassName (name); }
+
+ /// Returns the name and value of a member by index.
+ /// This will throw an error if the value is not an object of if the index is out of range. (Use
+ /// size() to find out how many members there are). To get a named value from an object, you can
+ /// use operator[].
+ /// @see size
+ MemberNameAndValue getObjectMemberAt (uint32_t index) const { return value.getObjectMemberAt (index); }
+
+ /// Returns the value of a named member, or a void value if no such member exists.
+ /// Note that this returns a view of the parent Value, which will become invalid as soon as any
+ /// change is made to the parent Value.
+ /// This will throw an error if the value is not an object.
+ ValueView operator[] (std::string_view name) const { return value[name]; }
+
+ /// Returns the value of a named member, or a void value if no such member exists.
+ /// Note that this returns a view of the parent Value, which will become invalid as soon as any
+ /// change is made to the parent Value.
+ /// This will throw an error if the value is not an object.
+ ValueView operator[] (const char* name) const { return value[name]; }
+
+ /// Returns true if this is an object and contains the given member name.
+ bool hasObjectMember (std::string_view name) const { return value.hasObjectMember (name); }
+
+ /// Returns a ValueView of this Value. The ValueView will become invalid as soon as any change is made to this Value.
+ operator const ValueView&() const { return value; }
+
+ /// Returns a ValueView of this Value. The ValueView will become invalid as soon as any change is made to this Value.
+ const ValueView& getView() const { return value; }
+
+ /// Returns a mutable reference to the ValueView held inside this Value. This is only for use if you know what you're doing.
+ ValueView& getViewReference() { return value; }
+
+ /// Returns the type of this value.
+ const Type& getType() const { return value.getType(); }
+
+ /// Returns a pointer to the raw data that stores this value.
+ const void* getRawData() const { return packedData.data(); }
+ /// Returns a pointer to the raw data that stores this value.
+ void* getRawData() { return packedData.data(); }
+ /// Returns the size of the raw data that stores this value.
+ size_t getRawDataSize() const { return packedData.size(); }
+
+ /// Gets a pointer to the string dictionary that the view is using, or nullptr
+ /// if it doesn't have one.
+ StringDictionary* getDictionary() const { return value.getDictionary(); }
+
+ /// Stores a complete representation of this value and its type in a packed data format.
+ /// It can later be reloaded with Value::deserialise() or ValueView::deserialise().
+ /// The OutputStream object can be any class which has a method write (const void*, size_t).
+ /// The data format is:
+ /// - The serialised Type data, as written by Type::serialise()
+ /// - The block of value data, which is a copy of getRawData(), the size being Type::getValueDataSize()
+ /// - If any strings are in the dictionary, this is followed by a packed int for the total size of
+ /// the remaining string block, then a sequence of null-terminated strings. String handles are
+ /// encoded as a byte offset into this table, where the first character of the first string = 1.
+ /// @see Value::deserialise, ValueView::deserialise
+ template
+ void serialise (OutputStream&) const;
+
+ /// Returns an object containing a serialised representation of this value. This is a helper
+ /// function to make it easier to call serialise() without needing to use your own output
+ /// stream class.
+ SerialisedData serialise() const;
+
+ /// Recreates a Value from serialised data that was created by the Value::serialise() method.
+ /// Any errors while reading the data will cause an Error exception to be thrown.
+ /// The InputData object will be left pointing to any remaining data after the value has been read.
+ /// @see Value::serialise
+ static Value deserialise (InputData&);
+
+ /// @internal
+ Value (Type&&, const void*, size_t);
+ /// @internal
+ Value (Type&&, const void*, size_t, StringDictionary*);
+ /// @internal
+ Value (const Type&, const void*, size_t, StringDictionary*);
+
+private:
+ //==============================================================================
+ Value (const void*) = delete;
+ void appendData (const void*, size_t);
+ void appendValue (const ValueView&);
+ void appendMember (std::string_view, Type&&, const void*, size_t);
+ void changeMember (uint32_t, const Type&, void*, StringDictionary*);
+
+ std::vector packedData;
+ SimpleStringDictionary dictionary;
+ ValueView value;
+};
+
+//==============================================================================
+static Value createInt32 (int32_t);
+static Value createInt64 (int64_t);
+static Value createFloat32 (float);
+static Value createFloat64 (double);
+static Value createBool (bool);
+
+static Value createPrimitive (int32_t);
+static Value createPrimitive (int64_t);
+static Value createPrimitive (float);
+static Value createPrimitive (double);
+static Value createPrimitive (bool);
+
+static Value createString (std::string_view);
+
+/// Allocates a vector, populating it from an array of primitive values.
+template
+static Value createVector (const ElementType* sourceElements, uint32_t numElements);
+
+/// Allocates a vector, populating it using a functor to return the initial primitive values.
+/// The functor must be a class or lambda which takes a uint32_t index parameter and returns
+/// the primitive value for that index. The type of the returned primitive is used as the
+/// vector's element type.
+template
+static Value createVector (uint32_t numElements, const GetElementValue& getValueForIndex);
+
+/// Creates an empty array (to which elements can then be appended with addArrayElement)
+static Value createEmptyArray();
+
+/// Allocates an array, populating it using a functor to return the initial values.
+/// The functor must be a class or lambda which takes a uint32_t index parameter and returns
+/// either Value objects or primitive types to store at that index.
+template
+static Value createArray (uint32_t numElements, const GetElementValue& getValueForIndex);
+
+/// Allocates an array which is a packed array of vector primitives, populating it using a
+/// functor to return the initial values.
+/// The functor must be a class or lambda which takes two uint32_t index parameters (the outer
+/// and inner indices for the required element) and returns a primitive type to store at that
+/// location.
+template
+static Value createArray (uint32_t numArrayElements, uint32_t numVectorElements, const GetElementValue& getValueAt);
+
+/// Creates an array from an iterable container such as a std::vector. The container
+/// must contain either Values, or primitive elements which can be turned into Values.
+template
+static Value createArray (const ContainerType&);
+
+/// Allocates a copy of a packed array of vector primitives.
+template
+static Value create2DArray (const ElementType* sourceElements, uint32_t numArrayElements, uint32_t numVectorElements);
+
+/// Creates a view directly onto a packed array of primitives.
+/// The ValueView that is returned will not take a copy of the data, so its lifetime must be managed by the caller.
+template
+static ValueView createArrayView (ElementType* targetData, uint32_t numElements);
+
+/// Creates a view directly onto a packed array of vector primitives.
+/// The ValueView that is returned will not take a copy of the data, so its lifetime must be managed by the caller.
+template
+static ValueView create2DArrayView (ElementType* targetData, uint32_t numArrayElements, uint32_t numVectorElements);
+
+
+/// Returns a Value which is a new empty object.
+static Value createObject (std::string_view className);
+
+/// Returns a Value which is a new object, with some member values set.
+template
+static Value createObject (std::string_view className, Members&&... members);
+
+
+//==============================================================================
+// _ _ _ _
+// __| | ___ | |_ __ _ (_)| | ___
+// / _` | / _ \| __| / _` || || |/ __|
+// | (_| || __/| |_ | (_| || || |\__ \ _ _ _
+// \__,_| \___| \__| \__,_||_||_||___/(_)(_)(_)
+//
+// Code beyond this point is implementation detail...
+//
+//==============================================================================
+
+namespace
+{
+ template static constexpr bool matchesType() { return false; }
+ template static constexpr bool matchesType() { return std::is_same::value || matchesType(); }
+ template static constexpr bool isPrimitiveType() { return matchesType(); }
+ template static constexpr bool isStringType() { return matchesType(); }
+ template static constexpr bool isValueType() { return matchesType(); }
+ template static constexpr size_t getTypeSize() { return std::is_same::value ? sizeof (BoolStorageType) : sizeof (Type); }
+
+ template TargetType readUnaligned (const void* src)
+ {
+ if constexpr (std::is_same::value)
+ {
+ BoolStorageType b;
+ std::memcpy (std::addressof (b), src, sizeof (b));
+ return b != 0;
+ }
+ else
+ {
+ TargetType v;
+ std::memcpy (std::addressof (v), src, sizeof (v));
+ return v;
+ }
+ }
+
+ template void writeUnaligned (void* dest, TargetType src)
+ {
+ if constexpr (std::is_same::value)
+ {
+ BoolStorageType b = src ? 1 : 0;
+ std::memcpy (dest, std::addressof (b), sizeof (b));
+ }
+ else
+ {
+ std::memcpy (dest, std::addressof (src), sizeof (TargetType));
+ }
+ }
+
+ static inline void* allocateBytes (Allocator* a, size_t size)
+ {
+ #ifndef __clang_analyzer__ // this avoids some false positives in the Clang analyser
+ if (a != nullptr)
+ return a->allocate (size);
+
+ return std::malloc (size);
+ #endif
+ }
+
+ static inline void* resizeAllocationIfPossible (Allocator* a, void* data, size_t size)
+ {
+ if (a != nullptr)
+ return a->resizeIfPossible (data, size);
+
+ return std::realloc (data, size);
+ }
+
+ static inline void freeBytes (Allocator* a, void* data) noexcept
+ {
+ if (a != nullptr)
+ return a->free (data);
+
+ std::free (data);
+ }
+
+ template
+ ObjectType* allocateObject (Allocator* a, Args&&... args) { return new (allocateBytes (a, sizeof (ObjectType))) ObjectType (std::forward (args)...); }
+
+ template
+ void freeObject (Allocator* a, ObjectType* t) { if (t != nullptr) { static_cast(t)->~ObjectType(); freeBytes (a, t); } }
+
+ static inline std::string_view allocateString (Allocator* a, std::string_view s)
+ {
+ if (auto size = s.length())
+ {
+ auto data = static_cast (allocateBytes (a, size + 1));
+ std::memcpy (data, s.data(), size);
+ data[size] = 0;
+ return { data, size };
+ }
+
+ return {};
+ }
+
+ static inline void freeString (Allocator* a, std::string_view s) noexcept
+ {
+ freeBytes (a, const_cast (s.data()));
+ }
+}
+
+//==============================================================================
+template
+void* FixedPoolAllocator::allocate (size_t size)
+{
+ lastAllocationPosition = position;
+ auto result = pool + position;
+ auto newSize = position + ((size + 15u) & ~15u);
+
+ if (newSize > sizeof (pool))
+ throwError ("Out of local scratch space");
+
+ position = newSize;
+ return result;
+}
+
+template
+void* FixedPoolAllocator::resizeIfPossible (void* data, size_t requiredSize)
+{
+ if (pool + lastAllocationPosition != data)
+ return {};
+
+ position = lastAllocationPosition;
+ return allocate (requiredSize);
+}
+
+//==============================================================================
+// This as a minimal replacement for std::vector (necessary because of custom allocators)
+template
+struct Type::AllocatedVector
+{
+ AllocatedVector (Allocator* a) : allocator (a) {}
+ AllocatedVector (AllocatedVector&&) = delete;
+ AllocatedVector (const AllocatedVector&) = delete;
+
+ ~AllocatedVector() noexcept
+ {
+ for (decltype (size) i = 0; i < size; ++i)
+ items[i].~ObjectType();
+
+ freeBytes (allocator, items);
+ }
+
+ ObjectType* begin() const { return items; }
+ ObjectType* end() const { return items + size; }
+ bool empty() const { return size == 0; }
+ ObjectType& front() const { return *items; }
+ ObjectType& back() const { return items[size - 1]; }
+ ObjectType& operator[] (uint32_t i) const { return items[i]; }
+
+ void push_back (ObjectType&& o)
+ {
+ reserve (size + 1);
+ new (items + size) ObjectType (std::move (o));
+ ++size;
+ }
+
+ bool operator== (const AllocatedVector& other) const
+ {
+ if (size != other.size)
+ return false;
+
+ for (decltype (size) i = 0; i < size; ++i)
+ if (! (items[i] == other.items[i]))
+ return false;
+
+ return true;
+ }
+
+ void reserve (uint32_t needed)
+ {
+ if (capacity < needed)
+ {
+ needed = (needed + 7u) & ~7u;
+ auto bytesNeeded = sizeof (ObjectType) * needed;
+
+ if (auto reallocated = static_cast (resizeAllocationIfPossible (allocator, items, bytesNeeded)))
+ {
+ items = reallocated;
+ }
+ else
+ {
+ auto newItems = allocateBytes (allocator, bytesNeeded);
+
+ if (size != 0)
+ std::memcpy (newItems, items, size * sizeof (ObjectType));
+
+ freeBytes (allocator, items);
+ items = static_cast (newItems);
+ }
+
+ capacity = needed;
+ }
+ }
+
+ ObjectType* items = nullptr;
+ uint32_t size = 0, capacity = 0;
+ Allocator* const allocator;
+};
+
+inline size_t Type::Vector::getElementSize() const { return getPrimitiveSize (elementType); }
+inline size_t Type::Vector::getValueDataSize() const { return getElementSize() * numElements; }
+
+inline ElementTypeAndOffset Type::Vector::getElementInfo (uint32_t index) const
+{
+ check (index < numElements, "Index out of range");
+ return { Type (elementType), getElementSize() * index };
+}
+
+inline ElementTypeAndOffset Type::Vector::getElementRangeInfo (uint32_t start, uint32_t length) const
+{
+ check (start < numElements && start + length <= numElements, "Illegal element range");
+ return { Type (elementType, length), getElementSize() * start };
+}
+
+inline bool Type::Vector::operator== (const Vector& other) const { return elementType == other.elementType && numElements == other.numElements; }
+
+inline size_t Type::PrimitiveArray::getElementSize() const { auto sz = getPrimitiveSize (elementType); if (numVectorElements != 0) sz *= numVectorElements; return sz; }
+inline size_t Type::PrimitiveArray::getValueDataSize() const { return getElementSize() * numElements; }
+inline Type Type::PrimitiveArray::getElementType() const { return numVectorElements != 0 ? Type (elementType, numVectorElements) : Type (elementType); }
+
+inline ElementTypeAndOffset Type::PrimitiveArray::getElementRangeInfo (uint32_t start, uint32_t length) const
+{
+ check (start < numElements && start + length <= numElements, "Illegal element range");
+
+ Content c;
+ c.primitiveArray = { elementType, length, numVectorElements };
+
+ return { Type (MainType::primitiveArray, c, nullptr),
+ start * getPrimitiveSize (elementType) * (numVectorElements != 0 ? numVectorElements : 1) };
+}
+
+inline ElementTypeAndOffset Type::PrimitiveArray::getElementInfo (uint32_t index) const
+{
+ check (index < numElements, "Index out of range");
+ auto primitiveSize = getPrimitiveSize (elementType);
+
+ if (numVectorElements != 0)
+ return { Type (elementType, numVectorElements), primitiveSize * numVectorElements * index };
+
+ return { Type (elementType), primitiveSize * index };
+}
+
+inline bool Type::PrimitiveArray::operator== (const PrimitiveArray& other) const
+{
+ return elementType == other.elementType && numElements == other.numElements && numVectorElements == other.numVectorElements;
+}
+
+struct Type::ComplexArray
+{
+ ComplexArray() = delete;
+ ComplexArray (Allocator* a) : groups (a) {}
+ ComplexArray (const ComplexArray&) = delete;
+
+ ComplexArray (Allocator* a, const ComplexArray& other) : groups (a)
+ {
+ groups.reserve (other.groups.size);
+
+ for (auto& g : other.groups)
+ groups.push_back ({ a, g });
+ }
+
+ uint32_t size() const
+ {
+ uint32_t total = 0;
+
+ for (auto& g : groups)
+ total += g.repetitions;
+
+ return total;
+ }
+
+ Type getElementType (uint32_t index) const
+ {
+ uint32_t count = 0;
+
+ for (auto& g : groups)
+ {
+ count += g.repetitions;
+
+ if (index < count)
+ return g.elementType;
+ }
+
+ throwError ("Index out of range");
+ }
+
+ ElementTypeAndOffset getElementRangeInfo (Allocator* a, uint32_t start, uint32_t length) const
+ {
+ ElementTypeAndOffset info { Type (MainType::complexArray), 0 };
+ info.elementType.content.complexArray = allocateObject (a, a);
+ auto& destGroups = info.elementType.content.complexArray->groups;
+
+ for (auto& g : groups)
+ {
+ auto groupLen = g.repetitions;
+
+ if (start >= groupLen)
+ {
+ start -= groupLen;
+ info.offset += g.repetitions * g.elementType.getValueDataSize();
+ continue;
+ }
+
+ if (start > 0)
+ {
+ groupLen -= start;
+ info.offset += start * g.elementType.getValueDataSize();
+ start = 0;
+ }
+
+ if (length <= groupLen)
+ {
+ destGroups.push_back ({ length, Type (a, g.elementType) });
+ return info;
+ }
+
+ destGroups.push_back ({ groupLen, Type (a, g.elementType) });
+ length -= groupLen;
+ }
+
+ check (start == 0 && length == 0, "Illegal element range");
+ return info;
+ }
+
+ size_t getValueDataSize() const
+ {
+ size_t total = 0;
+
+ for (auto& g : groups)
+ total += g.repetitions * g.elementType.getValueDataSize();
+
+ return total;
+ }
+
+ bool usesStrings() const
+ {
+ for (auto& g : groups)
+ if (g.elementType.usesStrings())
+ return true;
+
+ return false;
+ }
+
+ template void visitStringHandles (size_t offset, const Visitor& visitor) const
+ {
+ for (auto& g : groups)
+ {
+ auto elementSize = g.elementType.getValueDataSize();
+
+ if (g.elementType.usesStrings())
+ {
+ for (uint32_t i = 0; i < g.repetitions; ++i)
+ {
+ g.elementType.visitStringHandles (offset, visitor);
+ offset += elementSize;
+ }
+ }
+ else
+ {
+ offset += elementSize * g.repetitions;
+ }
+ }
+ }
+
+ ElementTypeAndOffset getElementInfo (uint32_t index) const
+ {
+ size_t offset = 0;
+
+ for (auto& g : groups)
+ {
+ auto elementSize = g.elementType.getValueDataSize();
+
+ if (index < g.repetitions)
+ return { g.elementType, offset + elementSize * index };
+
+ index -= g.repetitions;
+ offset += elementSize * g.repetitions;
+ }
+
+ throwError ("Index out of range");
+ }
+
+ void addElements (Type&& elementType, uint32_t numElementsToAdd)
+ {
+ if (! groups.empty() && groups.back().elementType == elementType)
+ groups.back().repetitions += numElementsToAdd;
+ else
+ groups.push_back ({ numElementsToAdd, std::move (elementType) });
+ }
+
+ bool operator== (const ComplexArray& other) const { return groups == other.groups; }
+ bool isArrayOfVectors() const { return groups.size == 1 && groups.front().elementType.isVector(); }
+ bool isUniform() const { return groups.empty() || groups.size == 1; }
+
+ Type getUniformType() const
+ {
+ check (groups.size == 1, "This array does not contain a single element type");
+ return groups.front().elementType;
+ }
+
+ struct RepeatedGroup
+ {
+ RepeatedGroup (const RepeatedGroup&) = delete;
+ RepeatedGroup (RepeatedGroup&&) = default;
+ RepeatedGroup (uint32_t reps, Type&& element) : repetitions (reps), elementType (std::move (element)) {}
+ RepeatedGroup (Allocator* a, const RepeatedGroup& other) : repetitions (other.repetitions), elementType (a, other.elementType) {}
+
+ uint32_t repetitions;
+ Type elementType;
+
+ bool operator== (const RepeatedGroup& other) const { return repetitions == other.repetitions
+ && elementType == other.elementType; }
+ };
+
+ AllocatedVector groups;
+};
+
+struct Type::Object
+{
+ Object() = delete;
+ Object (const Object&) = delete;
+ Object (Allocator* a, std::string_view name) : className (allocateString (a, name)), members (a) {}
+
+ Object (Allocator* a, const Object& other) : className (allocateString (a, other.className)), members (a)
+ {
+ members.reserve (other.members.size);
+
+ for (auto& m : other.members)
+ members.push_back ({ allocateString (a, m.name), Type (a, m.type) });
+ }
+
+ ~Object() noexcept
+ {
+ freeString (members.allocator, className);
+
+ for (auto& m : members)
+ freeString (members.allocator, m.name);
+ }
+
+ std::string_view className;
+ AllocatedVector members;
+
+ size_t getValueDataSize() const
+ {
+ size_t total = 0;
+
+ for (auto& m : members)
+ total += m.type.getValueDataSize();
+
+ return total;
+ }
+
+ bool usesStrings() const
+ {
+ for (auto& m : members)
+ if (m.type.usesStrings())
+ return true;
+
+ return false;
+ }
+
+ template void visitStringHandles (size_t offset, const Visitor& visitor) const
+ {
+ for (uint32_t i = 0; i < members.size; ++i)
+ {
+ members[i].type.visitStringHandles (offset, visitor);
+ offset += members[i].type.getValueDataSize();
+ }
+ }
+
+ ElementTypeAndOffset getElementInfo (uint32_t index) const
+ {
+ size_t offset = 0;
+
+ for (uint32_t i = 0; i < members.size; ++i)
+ {
+ if (i == index)
+ return { members[i].type, offset };
+
+ offset += members[i].type.getValueDataSize();
+ }
+
+ throwError ("Index out of range");
+ }
+
+ bool operator== (const Object& other) const
+ {
+ if (className != other.className)
+ return false;
+
+ if (members.size != other.members.size)
+ return false;
+
+ for (uint32_t i = 0; i < members.size; ++i)
+ if (members[i].name != other.members[i].name
+ || members[i].type != other.members[i].type)
+ return false;
+
+ return true;
+ }
+};
+
+inline Type::Type (Type&& other) : mainType (other.mainType), content (other.content), allocator (other.allocator)
+{
+ other.mainType = MainType::void_;
+}
+
+inline void Type::allocateCopy (const Type& other)
+{
+ if (isType (MainType::complexArray)) content.complexArray = allocateObject (allocator, allocator, *other.content.complexArray);
+ else if (isObject()) content.object = allocateObject