| @@ -353,6 +353,7 @@ OBJECTS := \ | |||||
| $(OBJDIR)/juce_android_Windowing_2a620a72.o \ | $(OBJDIR)/juce_android_Windowing_2a620a72.o \ | ||||
| $(OBJDIR)/juce_CharacterFunctions_b1a5ac62.o \ | $(OBJDIR)/juce_CharacterFunctions_b1a5ac62.o \ | ||||
| $(OBJDIR)/juce_Identifier_e99ee619.o \ | $(OBJDIR)/juce_Identifier_e99ee619.o \ | ||||
| $(OBJDIR)/juce_JSON_bbf64af8.o \ | |||||
| $(OBJDIR)/juce_LocalisedStrings_3ddfa55e.o \ | $(OBJDIR)/juce_LocalisedStrings_3ddfa55e.o \ | ||||
| $(OBJDIR)/juce_String_80587b01.o \ | $(OBJDIR)/juce_String_80587b01.o \ | ||||
| $(OBJDIR)/juce_StringArray_4aaa67a2.o \ | $(OBJDIR)/juce_StringArray_4aaa67a2.o \ | ||||
| @@ -1956,6 +1957,11 @@ $(OBJDIR)/juce_Identifier_e99ee619.o: ../../src/text/juce_Identifier.cpp | |||||
| @echo "Compiling juce_Identifier.cpp" | @echo "Compiling juce_Identifier.cpp" | ||||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
| $(OBJDIR)/juce_JSON_bbf64af8.o: ../../src/text/juce_JSON.cpp | |||||
| -@mkdir -p $(OBJDIR) | |||||
| @echo "Compiling juce_JSON.cpp" | |||||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||||
| $(OBJDIR)/juce_LocalisedStrings_3ddfa55e.o: ../../src/text/juce_LocalisedStrings.cpp | $(OBJDIR)/juce_LocalisedStrings_3ddfa55e.o: ../../src/text/juce_LocalisedStrings.cpp | ||||
| -@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
| @echo "Compiling juce_LocalisedStrings.cpp" | @echo "Compiling juce_LocalisedStrings.cpp" | ||||
| @@ -348,6 +348,7 @@ | |||||
| CE9A64287FCEF00DD2BA6AEE = { isa = PBXBuildFile; fileRef = FCD02A40985242A8A6648311; }; | CE9A64287FCEF00DD2BA6AEE = { isa = PBXBuildFile; fileRef = FCD02A40985242A8A6648311; }; | ||||
| 2AC6F3BFAAA21E21076A9F8D = { isa = PBXBuildFile; fileRef = 76E2084D2148068F9138A816; }; | 2AC6F3BFAAA21E21076A9F8D = { isa = PBXBuildFile; fileRef = 76E2084D2148068F9138A816; }; | ||||
| B8DD4DB0BD1A6B38BBF92413 = { isa = PBXBuildFile; fileRef = 8273A206FB309671284959DD; }; | B8DD4DB0BD1A6B38BBF92413 = { isa = PBXBuildFile; fileRef = 8273A206FB309671284959DD; }; | ||||
| 1C0B1362E81C8B073BF0DCEC = { isa = PBXBuildFile; fileRef = 644FD6155385BC3AA270FB5D; }; | |||||
| 63BEC07A51CB8E516B38ECD4 = { isa = PBXBuildFile; fileRef = 4A97C8D2FF6454DDD3AF4BE5; }; | 63BEC07A51CB8E516B38ECD4 = { isa = PBXBuildFile; fileRef = 4A97C8D2FF6454DDD3AF4BE5; }; | ||||
| C8F81E843F446868FAD88197 = { isa = PBXBuildFile; fileRef = B507B4A8712A54D7A8C03223; }; | C8F81E843F446868FAD88197 = { isa = PBXBuildFile; fileRef = B507B4A8712A54D7A8C03223; }; | ||||
| 50D91A2EC0ABF894E612D936 = { isa = PBXBuildFile; fileRef = 23252E4C97AEFAE0C5EEAA77; }; | 50D91A2EC0ABF894E612D936 = { isa = PBXBuildFile; fileRef = 23252E4C97AEFAE0C5EEAA77; }; | ||||
| @@ -1052,12 +1053,14 @@ | |||||
| FCD02A40985242A8A6648311 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_android_Windowing.cpp; path = ../../src/native/android/juce_android_Windowing.cpp; sourceTree = SOURCE_ROOT; }; | FCD02A40985242A8A6648311 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_android_Windowing.cpp; path = ../../src/native/android/juce_android_Windowing.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| 76E2084D2148068F9138A816 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_CharacterFunctions.cpp; path = ../../src/text/juce_CharacterFunctions.cpp; sourceTree = SOURCE_ROOT; }; | 76E2084D2148068F9138A816 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_CharacterFunctions.cpp; path = ../../src/text/juce_CharacterFunctions.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| 33F16EE4F38C9B76E7FAEF78 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharacterFunctions.h; path = ../../src/text/juce_CharacterFunctions.h; sourceTree = SOURCE_ROOT; }; | 33F16EE4F38C9B76E7FAEF78 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharacterFunctions.h; path = ../../src/text/juce_CharacterFunctions.h; sourceTree = SOURCE_ROOT; }; | ||||
| 4007410FACA2F865FD8EF769 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF8.h; path = ../../src/text/juce_CharPointer_UTF8.h; sourceTree = SOURCE_ROOT; }; | |||||
| 72F5ED2E8B945988C37EA9CF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_ASCII.h; path = ../../src/text/juce_CharPointer_ASCII.h; sourceTree = SOURCE_ROOT; }; | |||||
| 663746215E9BA6C761172B85 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF16.h; path = ../../src/text/juce_CharPointer_UTF16.h; sourceTree = SOURCE_ROOT; }; | 663746215E9BA6C761172B85 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF16.h; path = ../../src/text/juce_CharPointer_UTF16.h; sourceTree = SOURCE_ROOT; }; | ||||
| C3FD9D93626F80A45F9B6DDE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF32.h; path = ../../src/text/juce_CharPointer_UTF32.h; sourceTree = SOURCE_ROOT; }; | C3FD9D93626F80A45F9B6DDE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF32.h; path = ../../src/text/juce_CharPointer_UTF32.h; sourceTree = SOURCE_ROOT; }; | ||||
| 72F5ED2E8B945988C37EA9CF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_ASCII.h; path = ../../src/text/juce_CharPointer_ASCII.h; sourceTree = SOURCE_ROOT; }; | |||||
| 4007410FACA2F865FD8EF769 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF8.h; path = ../../src/text/juce_CharPointer_UTF8.h; sourceTree = SOURCE_ROOT; }; | |||||
| 8273A206FB309671284959DD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Identifier.cpp; path = ../../src/text/juce_Identifier.cpp; sourceTree = SOURCE_ROOT; }; | 8273A206FB309671284959DD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Identifier.cpp; path = ../../src/text/juce_Identifier.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| BF888BC540B64D5C61E46A34 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Identifier.h; path = ../../src/text/juce_Identifier.h; sourceTree = SOURCE_ROOT; }; | BF888BC540B64D5C61E46A34 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Identifier.h; path = ../../src/text/juce_Identifier.h; sourceTree = SOURCE_ROOT; }; | ||||
| 644FD6155385BC3AA270FB5D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_JSON.cpp; path = ../../src/text/juce_JSON.cpp; sourceTree = SOURCE_ROOT; }; | |||||
| CB092FB152F43900272F8E43 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_JSON.h; path = ../../src/text/juce_JSON.h; sourceTree = SOURCE_ROOT; }; | |||||
| 4A97C8D2FF6454DDD3AF4BE5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_LocalisedStrings.cpp; path = ../../src/text/juce_LocalisedStrings.cpp; sourceTree = SOURCE_ROOT; }; | 4A97C8D2FF6454DDD3AF4BE5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_LocalisedStrings.cpp; path = ../../src/text/juce_LocalisedStrings.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| 2AA21CDC91EA122266EBD780 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_LocalisedStrings.h; path = ../../src/text/juce_LocalisedStrings.h; sourceTree = SOURCE_ROOT; }; | 2AA21CDC91EA122266EBD780 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_LocalisedStrings.h; path = ../../src/text/juce_LocalisedStrings.h; sourceTree = SOURCE_ROOT; }; | ||||
| 35DA3E75DDB03BB35794289B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_NewLine.h; path = ../../src/text/juce_NewLine.h; sourceTree = SOURCE_ROOT; }; | 35DA3E75DDB03BB35794289B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_NewLine.h; path = ../../src/text/juce_NewLine.h; sourceTree = SOURCE_ROOT; }; | ||||
| @@ -1894,12 +1897,14 @@ | |||||
| C6B52BCD0CB1B809D6DE555A = { isa = PBXGroup; children = ( | C6B52BCD0CB1B809D6DE555A = { isa = PBXGroup; children = ( | ||||
| 76E2084D2148068F9138A816, | 76E2084D2148068F9138A816, | ||||
| 33F16EE4F38C9B76E7FAEF78, | 33F16EE4F38C9B76E7FAEF78, | ||||
| 4007410FACA2F865FD8EF769, | |||||
| 72F5ED2E8B945988C37EA9CF, | |||||
| 663746215E9BA6C761172B85, | 663746215E9BA6C761172B85, | ||||
| C3FD9D93626F80A45F9B6DDE, | C3FD9D93626F80A45F9B6DDE, | ||||
| 72F5ED2E8B945988C37EA9CF, | |||||
| 4007410FACA2F865FD8EF769, | |||||
| 8273A206FB309671284959DD, | 8273A206FB309671284959DD, | ||||
| BF888BC540B64D5C61E46A34, | BF888BC540B64D5C61E46A34, | ||||
| 644FD6155385BC3AA270FB5D, | |||||
| CB092FB152F43900272F8E43, | |||||
| 4A97C8D2FF6454DDD3AF4BE5, | 4A97C8D2FF6454DDD3AF4BE5, | ||||
| 2AA21CDC91EA122266EBD780, | 2AA21CDC91EA122266EBD780, | ||||
| 35DA3E75DDB03BB35794289B, | 35DA3E75DDB03BB35794289B, | ||||
| @@ -2391,6 +2396,7 @@ | |||||
| CE9A64287FCEF00DD2BA6AEE, | CE9A64287FCEF00DD2BA6AEE, | ||||
| 2AC6F3BFAAA21E21076A9F8D, | 2AC6F3BFAAA21E21076A9F8D, | ||||
| B8DD4DB0BD1A6B38BBF92413, | B8DD4DB0BD1A6B38BBF92413, | ||||
| 1C0B1362E81C8B073BF0DCEC, | |||||
| 63BEC07A51CB8E516B38ECD4, | 63BEC07A51CB8E516B38ECD4, | ||||
| C8F81E843F446868FAD88197, | C8F81E843F446868FAD88197, | ||||
| 50D91A2EC0ABF894E612D936, | 50D91A2EC0ABF894E612D936, | ||||
| @@ -962,12 +962,14 @@ | |||||
| <Filter Name="text"> | <Filter Name="text"> | ||||
| <File RelativePath="..\..\src\text\juce_CharacterFunctions.cpp"/> | <File RelativePath="..\..\src\text\juce_CharacterFunctions.cpp"/> | ||||
| <File RelativePath="..\..\src\text\juce_CharacterFunctions.h"/> | <File RelativePath="..\..\src\text\juce_CharacterFunctions.h"/> | ||||
| <File RelativePath="..\..\src\text\juce_CharPointer_UTF8.h"/> | |||||
| <File RelativePath="..\..\src\text\juce_CharPointer_ASCII.h"/> | |||||
| <File RelativePath="..\..\src\text\juce_CharPointer_UTF16.h"/> | <File RelativePath="..\..\src\text\juce_CharPointer_UTF16.h"/> | ||||
| <File RelativePath="..\..\src\text\juce_CharPointer_UTF32.h"/> | <File RelativePath="..\..\src\text\juce_CharPointer_UTF32.h"/> | ||||
| <File RelativePath="..\..\src\text\juce_CharPointer_ASCII.h"/> | |||||
| <File RelativePath="..\..\src\text\juce_CharPointer_UTF8.h"/> | |||||
| <File RelativePath="..\..\src\text\juce_Identifier.cpp"/> | <File RelativePath="..\..\src\text\juce_Identifier.cpp"/> | ||||
| <File RelativePath="..\..\src\text\juce_Identifier.h"/> | <File RelativePath="..\..\src\text\juce_Identifier.h"/> | ||||
| <File RelativePath="..\..\src\text\juce_JSON.cpp"/> | |||||
| <File RelativePath="..\..\src\text\juce_JSON.h"/> | |||||
| <File RelativePath="..\..\src\text\juce_LocalisedStrings.cpp"/> | <File RelativePath="..\..\src\text\juce_LocalisedStrings.cpp"/> | ||||
| <File RelativePath="..\..\src\text\juce_LocalisedStrings.h"/> | <File RelativePath="..\..\src\text\juce_LocalisedStrings.h"/> | ||||
| <File RelativePath="..\..\src\text\juce_NewLine.h"/> | <File RelativePath="..\..\src\text\juce_NewLine.h"/> | ||||
| @@ -962,12 +962,14 @@ | |||||
| <Filter Name="text"> | <Filter Name="text"> | ||||
| <File RelativePath="..\..\src\text\juce_CharacterFunctions.cpp"/> | <File RelativePath="..\..\src\text\juce_CharacterFunctions.cpp"/> | ||||
| <File RelativePath="..\..\src\text\juce_CharacterFunctions.h"/> | <File RelativePath="..\..\src\text\juce_CharacterFunctions.h"/> | ||||
| <File RelativePath="..\..\src\text\juce_CharPointer_UTF8.h"/> | |||||
| <File RelativePath="..\..\src\text\juce_CharPointer_ASCII.h"/> | |||||
| <File RelativePath="..\..\src\text\juce_CharPointer_UTF16.h"/> | <File RelativePath="..\..\src\text\juce_CharPointer_UTF16.h"/> | ||||
| <File RelativePath="..\..\src\text\juce_CharPointer_UTF32.h"/> | <File RelativePath="..\..\src\text\juce_CharPointer_UTF32.h"/> | ||||
| <File RelativePath="..\..\src\text\juce_CharPointer_ASCII.h"/> | |||||
| <File RelativePath="..\..\src\text\juce_CharPointer_UTF8.h"/> | |||||
| <File RelativePath="..\..\src\text\juce_Identifier.cpp"/> | <File RelativePath="..\..\src\text\juce_Identifier.cpp"/> | ||||
| <File RelativePath="..\..\src\text\juce_Identifier.h"/> | <File RelativePath="..\..\src\text\juce_Identifier.h"/> | ||||
| <File RelativePath="..\..\src\text\juce_JSON.cpp"/> | |||||
| <File RelativePath="..\..\src\text\juce_JSON.h"/> | |||||
| <File RelativePath="..\..\src\text\juce_LocalisedStrings.cpp"/> | <File RelativePath="..\..\src\text\juce_LocalisedStrings.cpp"/> | ||||
| <File RelativePath="..\..\src\text\juce_LocalisedStrings.h"/> | <File RelativePath="..\..\src\text\juce_LocalisedStrings.h"/> | ||||
| <File RelativePath="..\..\src\text\juce_NewLine.h"/> | <File RelativePath="..\..\src\text\juce_NewLine.h"/> | ||||
| @@ -964,12 +964,14 @@ | |||||
| <Filter Name="text"> | <Filter Name="text"> | ||||
| <File RelativePath="..\..\src\text\juce_CharacterFunctions.cpp"/> | <File RelativePath="..\..\src\text\juce_CharacterFunctions.cpp"/> | ||||
| <File RelativePath="..\..\src\text\juce_CharacterFunctions.h"/> | <File RelativePath="..\..\src\text\juce_CharacterFunctions.h"/> | ||||
| <File RelativePath="..\..\src\text\juce_CharPointer_UTF8.h"/> | |||||
| <File RelativePath="..\..\src\text\juce_CharPointer_ASCII.h"/> | |||||
| <File RelativePath="..\..\src\text\juce_CharPointer_UTF16.h"/> | <File RelativePath="..\..\src\text\juce_CharPointer_UTF16.h"/> | ||||
| <File RelativePath="..\..\src\text\juce_CharPointer_UTF32.h"/> | <File RelativePath="..\..\src\text\juce_CharPointer_UTF32.h"/> | ||||
| <File RelativePath="..\..\src\text\juce_CharPointer_ASCII.h"/> | |||||
| <File RelativePath="..\..\src\text\juce_CharPointer_UTF8.h"/> | |||||
| <File RelativePath="..\..\src\text\juce_Identifier.cpp"/> | <File RelativePath="..\..\src\text\juce_Identifier.cpp"/> | ||||
| <File RelativePath="..\..\src\text\juce_Identifier.h"/> | <File RelativePath="..\..\src\text\juce_Identifier.h"/> | ||||
| <File RelativePath="..\..\src\text\juce_JSON.cpp"/> | |||||
| <File RelativePath="..\..\src\text\juce_JSON.h"/> | |||||
| <File RelativePath="..\..\src\text\juce_LocalisedStrings.cpp"/> | <File RelativePath="..\..\src\text\juce_LocalisedStrings.cpp"/> | ||||
| <File RelativePath="..\..\src\text\juce_LocalisedStrings.h"/> | <File RelativePath="..\..\src\text\juce_LocalisedStrings.h"/> | ||||
| <File RelativePath="..\..\src\text\juce_NewLine.h"/> | <File RelativePath="..\..\src\text\juce_NewLine.h"/> | ||||
| @@ -436,6 +436,7 @@ | |||||
| <ClCompile Include="..\..\src\native\android\juce_android_Windowing.cpp"/> | <ClCompile Include="..\..\src\native\android\juce_android_Windowing.cpp"/> | ||||
| <ClCompile Include="..\..\src\text\juce_CharacterFunctions.cpp"/> | <ClCompile Include="..\..\src\text\juce_CharacterFunctions.cpp"/> | ||||
| <ClCompile Include="..\..\src\text\juce_Identifier.cpp"/> | <ClCompile Include="..\..\src\text\juce_Identifier.cpp"/> | ||||
| <ClCompile Include="..\..\src\text\juce_JSON.cpp"/> | |||||
| <ClCompile Include="..\..\src\text\juce_LocalisedStrings.cpp"/> | <ClCompile Include="..\..\src\text\juce_LocalisedStrings.cpp"/> | ||||
| <ClCompile Include="..\..\src\text\juce_String.cpp"/> | <ClCompile Include="..\..\src\text\juce_String.cpp"/> | ||||
| <ClCompile Include="..\..\src\text\juce_StringArray.cpp"/> | <ClCompile Include="..\..\src\text\juce_StringArray.cpp"/> | ||||
| @@ -790,11 +791,12 @@ | |||||
| <ClInclude Include="..\..\src\native\windows\juce_win32_NativeIncludes.h"/> | <ClInclude Include="..\..\src\native\windows\juce_win32_NativeIncludes.h"/> | ||||
| <ClInclude Include="..\..\src\native\android\juce_android_NativeIncludes.h"/> | <ClInclude Include="..\..\src\native\android\juce_android_NativeIncludes.h"/> | ||||
| <ClInclude Include="..\..\src\text\juce_CharacterFunctions.h"/> | <ClInclude Include="..\..\src\text\juce_CharacterFunctions.h"/> | ||||
| <ClInclude Include="..\..\src\text\juce_CharPointer_UTF8.h"/> | |||||
| <ClInclude Include="..\..\src\text\juce_CharPointer_ASCII.h"/> | |||||
| <ClInclude Include="..\..\src\text\juce_CharPointer_UTF16.h"/> | <ClInclude Include="..\..\src\text\juce_CharPointer_UTF16.h"/> | ||||
| <ClInclude Include="..\..\src\text\juce_CharPointer_UTF32.h"/> | <ClInclude Include="..\..\src\text\juce_CharPointer_UTF32.h"/> | ||||
| <ClInclude Include="..\..\src\text\juce_CharPointer_ASCII.h"/> | |||||
| <ClInclude Include="..\..\src\text\juce_CharPointer_UTF8.h"/> | |||||
| <ClInclude Include="..\..\src\text\juce_Identifier.h"/> | <ClInclude Include="..\..\src\text\juce_Identifier.h"/> | ||||
| <ClInclude Include="..\..\src\text\juce_JSON.h"/> | |||||
| <ClInclude Include="..\..\src\text\juce_LocalisedStrings.h"/> | <ClInclude Include="..\..\src\text\juce_LocalisedStrings.h"/> | ||||
| <ClInclude Include="..\..\src\text\juce_NewLine.h"/> | <ClInclude Include="..\..\src\text\juce_NewLine.h"/> | ||||
| <ClInclude Include="..\..\src\text\juce_String.h"/> | <ClInclude Include="..\..\src\text\juce_String.h"/> | ||||
| @@ -1243,6 +1243,9 @@ | |||||
| <ClCompile Include="..\..\src\text\juce_Identifier.cpp"> | <ClCompile Include="..\..\src\text\juce_Identifier.cpp"> | ||||
| <Filter>Juce\Source\text</Filter> | <Filter>Juce\Source\text</Filter> | ||||
| </ClCompile> | </ClCompile> | ||||
| <ClCompile Include="..\..\src\text\juce_JSON.cpp"> | |||||
| <Filter>Juce\Source\text</Filter> | |||||
| </ClCompile> | |||||
| <ClCompile Include="..\..\src\text\juce_LocalisedStrings.cpp"> | <ClCompile Include="..\..\src\text\juce_LocalisedStrings.cpp"> | ||||
| <Filter>Juce\Source\text</Filter> | <Filter>Juce\Source\text</Filter> | ||||
| </ClCompile> | </ClCompile> | ||||
| @@ -2301,7 +2304,7 @@ | |||||
| <ClInclude Include="..\..\src\text\juce_CharacterFunctions.h"> | <ClInclude Include="..\..\src\text\juce_CharacterFunctions.h"> | ||||
| <Filter>Juce\Source\text</Filter> | <Filter>Juce\Source\text</Filter> | ||||
| </ClInclude> | </ClInclude> | ||||
| <ClInclude Include="..\..\src\text\juce_CharPointer_UTF8.h"> | |||||
| <ClInclude Include="..\..\src\text\juce_CharPointer_ASCII.h"> | |||||
| <Filter>Juce\Source\text</Filter> | <Filter>Juce\Source\text</Filter> | ||||
| </ClInclude> | </ClInclude> | ||||
| <ClInclude Include="..\..\src\text\juce_CharPointer_UTF16.h"> | <ClInclude Include="..\..\src\text\juce_CharPointer_UTF16.h"> | ||||
| @@ -2310,12 +2313,15 @@ | |||||
| <ClInclude Include="..\..\src\text\juce_CharPointer_UTF32.h"> | <ClInclude Include="..\..\src\text\juce_CharPointer_UTF32.h"> | ||||
| <Filter>Juce\Source\text</Filter> | <Filter>Juce\Source\text</Filter> | ||||
| </ClInclude> | </ClInclude> | ||||
| <ClInclude Include="..\..\src\text\juce_CharPointer_ASCII.h"> | |||||
| <ClInclude Include="..\..\src\text\juce_CharPointer_UTF8.h"> | |||||
| <Filter>Juce\Source\text</Filter> | <Filter>Juce\Source\text</Filter> | ||||
| </ClInclude> | </ClInclude> | ||||
| <ClInclude Include="..\..\src\text\juce_Identifier.h"> | <ClInclude Include="..\..\src\text\juce_Identifier.h"> | ||||
| <Filter>Juce\Source\text</Filter> | <Filter>Juce\Source\text</Filter> | ||||
| </ClInclude> | </ClInclude> | ||||
| <ClInclude Include="..\..\src\text\juce_JSON.h"> | |||||
| <Filter>Juce\Source\text</Filter> | |||||
| </ClInclude> | |||||
| <ClInclude Include="..\..\src\text\juce_LocalisedStrings.h"> | <ClInclude Include="..\..\src\text\juce_LocalisedStrings.h"> | ||||
| <Filter>Juce\Source\text</Filter> | <Filter>Juce\Source\text</Filter> | ||||
| </ClInclude> | </ClInclude> | ||||
| @@ -348,6 +348,7 @@ | |||||
| CE9A64287FCEF00DD2BA6AEE = { isa = PBXBuildFile; fileRef = FCD02A40985242A8A6648311; }; | CE9A64287FCEF00DD2BA6AEE = { isa = PBXBuildFile; fileRef = FCD02A40985242A8A6648311; }; | ||||
| 2AC6F3BFAAA21E21076A9F8D = { isa = PBXBuildFile; fileRef = 76E2084D2148068F9138A816; }; | 2AC6F3BFAAA21E21076A9F8D = { isa = PBXBuildFile; fileRef = 76E2084D2148068F9138A816; }; | ||||
| B8DD4DB0BD1A6B38BBF92413 = { isa = PBXBuildFile; fileRef = 8273A206FB309671284959DD; }; | B8DD4DB0BD1A6B38BBF92413 = { isa = PBXBuildFile; fileRef = 8273A206FB309671284959DD; }; | ||||
| 1C0B1362E81C8B073BF0DCEC = { isa = PBXBuildFile; fileRef = 644FD6155385BC3AA270FB5D; }; | |||||
| 63BEC07A51CB8E516B38ECD4 = { isa = PBXBuildFile; fileRef = 4A97C8D2FF6454DDD3AF4BE5; }; | 63BEC07A51CB8E516B38ECD4 = { isa = PBXBuildFile; fileRef = 4A97C8D2FF6454DDD3AF4BE5; }; | ||||
| C8F81E843F446868FAD88197 = { isa = PBXBuildFile; fileRef = B507B4A8712A54D7A8C03223; }; | C8F81E843F446868FAD88197 = { isa = PBXBuildFile; fileRef = B507B4A8712A54D7A8C03223; }; | ||||
| 50D91A2EC0ABF894E612D936 = { isa = PBXBuildFile; fileRef = 23252E4C97AEFAE0C5EEAA77; }; | 50D91A2EC0ABF894E612D936 = { isa = PBXBuildFile; fileRef = 23252E4C97AEFAE0C5EEAA77; }; | ||||
| @@ -1052,12 +1053,14 @@ | |||||
| FCD02A40985242A8A6648311 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_android_Windowing.cpp; path = ../../src/native/android/juce_android_Windowing.cpp; sourceTree = SOURCE_ROOT; }; | FCD02A40985242A8A6648311 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_android_Windowing.cpp; path = ../../src/native/android/juce_android_Windowing.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| 76E2084D2148068F9138A816 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_CharacterFunctions.cpp; path = ../../src/text/juce_CharacterFunctions.cpp; sourceTree = SOURCE_ROOT; }; | 76E2084D2148068F9138A816 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_CharacterFunctions.cpp; path = ../../src/text/juce_CharacterFunctions.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| 33F16EE4F38C9B76E7FAEF78 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharacterFunctions.h; path = ../../src/text/juce_CharacterFunctions.h; sourceTree = SOURCE_ROOT; }; | 33F16EE4F38C9B76E7FAEF78 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharacterFunctions.h; path = ../../src/text/juce_CharacterFunctions.h; sourceTree = SOURCE_ROOT; }; | ||||
| 4007410FACA2F865FD8EF769 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF8.h; path = ../../src/text/juce_CharPointer_UTF8.h; sourceTree = SOURCE_ROOT; }; | |||||
| 72F5ED2E8B945988C37EA9CF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_ASCII.h; path = ../../src/text/juce_CharPointer_ASCII.h; sourceTree = SOURCE_ROOT; }; | |||||
| 663746215E9BA6C761172B85 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF16.h; path = ../../src/text/juce_CharPointer_UTF16.h; sourceTree = SOURCE_ROOT; }; | 663746215E9BA6C761172B85 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF16.h; path = ../../src/text/juce_CharPointer_UTF16.h; sourceTree = SOURCE_ROOT; }; | ||||
| C3FD9D93626F80A45F9B6DDE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF32.h; path = ../../src/text/juce_CharPointer_UTF32.h; sourceTree = SOURCE_ROOT; }; | C3FD9D93626F80A45F9B6DDE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF32.h; path = ../../src/text/juce_CharPointer_UTF32.h; sourceTree = SOURCE_ROOT; }; | ||||
| 72F5ED2E8B945988C37EA9CF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_ASCII.h; path = ../../src/text/juce_CharPointer_ASCII.h; sourceTree = SOURCE_ROOT; }; | |||||
| 4007410FACA2F865FD8EF769 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF8.h; path = ../../src/text/juce_CharPointer_UTF8.h; sourceTree = SOURCE_ROOT; }; | |||||
| 8273A206FB309671284959DD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Identifier.cpp; path = ../../src/text/juce_Identifier.cpp; sourceTree = SOURCE_ROOT; }; | 8273A206FB309671284959DD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Identifier.cpp; path = ../../src/text/juce_Identifier.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| BF888BC540B64D5C61E46A34 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Identifier.h; path = ../../src/text/juce_Identifier.h; sourceTree = SOURCE_ROOT; }; | BF888BC540B64D5C61E46A34 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Identifier.h; path = ../../src/text/juce_Identifier.h; sourceTree = SOURCE_ROOT; }; | ||||
| 644FD6155385BC3AA270FB5D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_JSON.cpp; path = ../../src/text/juce_JSON.cpp; sourceTree = SOURCE_ROOT; }; | |||||
| CB092FB152F43900272F8E43 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_JSON.h; path = ../../src/text/juce_JSON.h; sourceTree = SOURCE_ROOT; }; | |||||
| 4A97C8D2FF6454DDD3AF4BE5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_LocalisedStrings.cpp; path = ../../src/text/juce_LocalisedStrings.cpp; sourceTree = SOURCE_ROOT; }; | 4A97C8D2FF6454DDD3AF4BE5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_LocalisedStrings.cpp; path = ../../src/text/juce_LocalisedStrings.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| 2AA21CDC91EA122266EBD780 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_LocalisedStrings.h; path = ../../src/text/juce_LocalisedStrings.h; sourceTree = SOURCE_ROOT; }; | 2AA21CDC91EA122266EBD780 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_LocalisedStrings.h; path = ../../src/text/juce_LocalisedStrings.h; sourceTree = SOURCE_ROOT; }; | ||||
| 35DA3E75DDB03BB35794289B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_NewLine.h; path = ../../src/text/juce_NewLine.h; sourceTree = SOURCE_ROOT; }; | 35DA3E75DDB03BB35794289B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_NewLine.h; path = ../../src/text/juce_NewLine.h; sourceTree = SOURCE_ROOT; }; | ||||
| @@ -1894,12 +1897,14 @@ | |||||
| C6B52BCD0CB1B809D6DE555A = { isa = PBXGroup; children = ( | C6B52BCD0CB1B809D6DE555A = { isa = PBXGroup; children = ( | ||||
| 76E2084D2148068F9138A816, | 76E2084D2148068F9138A816, | ||||
| 33F16EE4F38C9B76E7FAEF78, | 33F16EE4F38C9B76E7FAEF78, | ||||
| 4007410FACA2F865FD8EF769, | |||||
| 72F5ED2E8B945988C37EA9CF, | |||||
| 663746215E9BA6C761172B85, | 663746215E9BA6C761172B85, | ||||
| C3FD9D93626F80A45F9B6DDE, | C3FD9D93626F80A45F9B6DDE, | ||||
| 72F5ED2E8B945988C37EA9CF, | |||||
| 4007410FACA2F865FD8EF769, | |||||
| 8273A206FB309671284959DD, | 8273A206FB309671284959DD, | ||||
| BF888BC540B64D5C61E46A34, | BF888BC540B64D5C61E46A34, | ||||
| 644FD6155385BC3AA270FB5D, | |||||
| CB092FB152F43900272F8E43, | |||||
| 4A97C8D2FF6454DDD3AF4BE5, | 4A97C8D2FF6454DDD3AF4BE5, | ||||
| 2AA21CDC91EA122266EBD780, | 2AA21CDC91EA122266EBD780, | ||||
| 35DA3E75DDB03BB35794289B, | 35DA3E75DDB03BB35794289B, | ||||
| @@ -2395,6 +2400,7 @@ | |||||
| CE9A64287FCEF00DD2BA6AEE, | CE9A64287FCEF00DD2BA6AEE, | ||||
| 2AC6F3BFAAA21E21076A9F8D, | 2AC6F3BFAAA21E21076A9F8D, | ||||
| B8DD4DB0BD1A6B38BBF92413, | B8DD4DB0BD1A6B38BBF92413, | ||||
| 1C0B1362E81C8B073BF0DCEC, | |||||
| 63BEC07A51CB8E516B38ECD4, | 63BEC07A51CB8E516B38ECD4, | ||||
| C8F81E843F446868FAD88197, | C8F81E843F446868FAD88197, | ||||
| 50D91A2EC0ABF894E612D936, | 50D91A2EC0ABF894E612D936, | ||||
| @@ -1497,18 +1497,20 @@ | |||||
| resource="0" file="src/text/juce_CharacterFunctions.cpp"/> | resource="0" file="src/text/juce_CharacterFunctions.cpp"/> | ||||
| <FILE id="McKZNzGvH" name="juce_CharacterFunctions.h" compile="0" resource="0" | <FILE id="McKZNzGvH" name="juce_CharacterFunctions.h" compile="0" resource="0" | ||||
| file="src/text/juce_CharacterFunctions.h"/> | file="src/text/juce_CharacterFunctions.h"/> | ||||
| <FILE id="vCX7K0" name="juce_CharPointer_UTF8.h" compile="0" resource="0" | |||||
| file="src/text/juce_CharPointer_UTF8.h"/> | |||||
| <FILE id="rdfOEc" name="juce_CharPointer_ASCII.h" compile="0" resource="0" | |||||
| file="src/text/juce_CharPointer_ASCII.h"/> | |||||
| <FILE id="KKhKRD" name="juce_CharPointer_UTF16.h" compile="0" resource="0" | <FILE id="KKhKRD" name="juce_CharPointer_UTF16.h" compile="0" resource="0" | ||||
| file="src/text/juce_CharPointer_UTF16.h"/> | file="src/text/juce_CharPointer_UTF16.h"/> | ||||
| <FILE id="rE1hlF" name="juce_CharPointer_UTF32.h" compile="0" resource="0" | <FILE id="rE1hlF" name="juce_CharPointer_UTF32.h" compile="0" resource="0" | ||||
| file="src/text/juce_CharPointer_UTF32.h"/> | file="src/text/juce_CharPointer_UTF32.h"/> | ||||
| <FILE id="rdfOEc" name="juce_CharPointer_ASCII.h" compile="0" resource="0" | |||||
| file="src/text/juce_CharPointer_ASCII.h"/> | |||||
| <FILE id="vCX7K0" name="juce_CharPointer_UTF8.h" compile="0" resource="0" | |||||
| file="src/text/juce_CharPointer_UTF8.h"/> | |||||
| <FILE id="iGtCiI8" name="juce_Identifier.cpp" compile="1" resource="0" | <FILE id="iGtCiI8" name="juce_Identifier.cpp" compile="1" resource="0" | ||||
| file="src/text/juce_Identifier.cpp"/> | file="src/text/juce_Identifier.cpp"/> | ||||
| <FILE id="CPlhWqs" name="juce_Identifier.h" compile="0" resource="0" | <FILE id="CPlhWqs" name="juce_Identifier.h" compile="0" resource="0" | ||||
| file="src/text/juce_Identifier.h"/> | file="src/text/juce_Identifier.h"/> | ||||
| <FILE id="dkmz9Q" name="juce_JSON.cpp" compile="1" resource="0" file="src/text/juce_JSON.cpp"/> | |||||
| <FILE id="Thklwk" name="juce_JSON.h" compile="0" resource="0" file="src/text/juce_JSON.h"/> | |||||
| <FILE id="HCYu323Km" name="juce_LocalisedStrings.cpp" compile="1" resource="0" | <FILE id="HCYu323Km" name="juce_LocalisedStrings.cpp" compile="1" resource="0" | ||||
| file="src/text/juce_LocalisedStrings.cpp"/> | file="src/text/juce_LocalisedStrings.cpp"/> | ||||
| <FILE id="omEQRDHD" name="juce_LocalisedStrings.h" compile="0" resource="0" | <FILE id="omEQRDHD" name="juce_LocalisedStrings.h" compile="0" resource="0" | ||||
| @@ -147,6 +147,7 @@ | |||||
| #include "../src/text/juce_StringPool.cpp" | #include "../src/text/juce_StringPool.cpp" | ||||
| #include "../src/text/juce_XmlDocument.cpp" | #include "../src/text/juce_XmlDocument.cpp" | ||||
| #include "../src/text/juce_XmlElement.cpp" | #include "../src/text/juce_XmlElement.cpp" | ||||
| #include "../src/text/juce_JSON.cpp" | |||||
| #include "../src/threads/juce_ReadWriteLock.cpp" | #include "../src/threads/juce_ReadWriteLock.cpp" | ||||
| #include "../src/threads/juce_Thread.cpp" | #include "../src/threads/juce_Thread.cpp" | ||||
| #include "../src/threads/juce_ThreadPool.cpp" | #include "../src/threads/juce_ThreadPool.cpp" | ||||
| @@ -4177,7 +4177,7 @@ Identifier::~Identifier() | |||||
| bool Identifier::isValidIdentifier (const String& possibleIdentifier) noexcept | bool Identifier::isValidIdentifier (const String& possibleIdentifier) noexcept | ||||
| { | { | ||||
| return possibleIdentifier.isNotEmpty() | return possibleIdentifier.isNotEmpty() | ||||
| && possibleIdentifier.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"); | |||||
| && possibleIdentifier.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-:"); | |||||
| } | } | ||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| @@ -4195,7 +4195,8 @@ enum VariantStreamMarkers | |||||
| varMarker_BoolFalse = 3, | varMarker_BoolFalse = 3, | ||||
| varMarker_Double = 4, | varMarker_Double = 4, | ||||
| varMarker_String = 5, | varMarker_String = 5, | ||||
| varMarker_Int64 = 6 | |||||
| varMarker_Int64 = 6, | |||||
| varMarker_Array = 7 | |||||
| }; | }; | ||||
| class var::VariantType | class var::VariantType | ||||
| @@ -4210,6 +4211,7 @@ public: | |||||
| virtual String toString (const ValueUnion&) const { return String::empty; } | virtual String toString (const ValueUnion&) const { return String::empty; } | ||||
| virtual bool toBool (const ValueUnion&) const noexcept { return false; } | virtual bool toBool (const ValueUnion&) const noexcept { return false; } | ||||
| virtual ReferenceCountedObject* toObject (const ValueUnion&) const noexcept { return nullptr; } | virtual ReferenceCountedObject* toObject (const ValueUnion&) const noexcept { return nullptr; } | ||||
| virtual Array<var>* toArray (const ValueUnion&) const noexcept { return 0; } | |||||
| virtual bool isVoid() const noexcept { return false; } | virtual bool isVoid() const noexcept { return false; } | ||||
| virtual bool isInt() const noexcept { return false; } | virtual bool isInt() const noexcept { return false; } | ||||
| @@ -4218,6 +4220,7 @@ public: | |||||
| virtual bool isDouble() const noexcept { return false; } | virtual bool isDouble() const noexcept { return false; } | ||||
| virtual bool isString() const noexcept { return false; } | virtual bool isString() const noexcept { return false; } | ||||
| virtual bool isObject() const noexcept { return false; } | virtual bool isObject() const noexcept { return false; } | ||||
| virtual bool isArray() const noexcept { return false; } | |||||
| virtual bool isMethod() const noexcept { return false; } | virtual bool isMethod() const noexcept { return false; } | ||||
| virtual void cleanUp (ValueUnion&) const noexcept {} | virtual void cleanUp (ValueUnion&) const noexcept {} | ||||
| @@ -4405,6 +4408,40 @@ public: | |||||
| } | } | ||||
| }; | }; | ||||
| class var::VariantType_Array : public var::VariantType | |||||
| { | |||||
| public: | |||||
| VariantType_Array() noexcept {} | |||||
| static const VariantType_Array instance; | |||||
| void cleanUp (ValueUnion& data) const noexcept { delete data.arrayValue; } | |||||
| void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.arrayValue = new Array<var> (*(source.arrayValue)); } | |||||
| String toString (const ValueUnion&) const { return "[Array]"; } | |||||
| bool isArray() const noexcept { return true; } | |||||
| Array<var>* toArray (const ValueUnion& data) const noexcept { return data.arrayValue; } | |||||
| bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept | |||||
| { | |||||
| const Array<var>* const otherArray = otherType.toArray (otherData); | |||||
| return otherArray != nullptr && *otherArray == *(data.arrayValue); | |||||
| } | |||||
| void writeToStream (const ValueUnion& data, OutputStream& output) const | |||||
| { | |||||
| MemoryOutputStream buffer (512); | |||||
| const int numItems = data.arrayValue->size(); | |||||
| buffer.writeCompressedInt (numItems); | |||||
| for (int i = 0; i < numItems; ++i) | |||||
| data.arrayValue->getReference(i).writeToStream (buffer); | |||||
| output.writeCompressedInt (1 + buffer.getDataSize()); | |||||
| output.writeByte (varMarker_Array); | |||||
| output << buffer; | |||||
| } | |||||
| }; | |||||
| class var::VariantType_Method : public var::VariantType | class var::VariantType_Method : public var::VariantType | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -4434,6 +4471,7 @@ const var::VariantType_Bool var::VariantType_Bool::instance; | |||||
| const var::VariantType_Double var::VariantType_Double::instance; | const var::VariantType_Double var::VariantType_Double::instance; | ||||
| const var::VariantType_String var::VariantType_String::instance; | const var::VariantType_String var::VariantType_String::instance; | ||||
| const var::VariantType_Object var::VariantType_Object::instance; | const var::VariantType_Object var::VariantType_Object::instance; | ||||
| const var::VariantType_Array var::VariantType_Array::instance; | |||||
| const var::VariantType_Method var::VariantType_Method::instance; | const var::VariantType_Method var::VariantType_Method::instance; | ||||
| var::var() noexcept : type (&VariantType_Void::instance) | var::var() noexcept : type (&VariantType_Void::instance) | ||||
| @@ -4487,6 +4525,11 @@ var::var (const wchar_t* const value_) : type (&VariantType_String::instance) | |||||
| new (value.stringValue) String (value_); | new (value.stringValue) String (value_); | ||||
| } | } | ||||
| var::var (const Array<var>& value_) : type (&VariantType_Array::instance) | |||||
| { | |||||
| value.arrayValue = new Array<var> (value_); | |||||
| } | |||||
| var::var (ReferenceCountedObject* const object) : type (&VariantType_Object::instance) | var::var (ReferenceCountedObject* const object) : type (&VariantType_Object::instance) | ||||
| { | { | ||||
| value.objectValue = object; | value.objectValue = object; | ||||
| @@ -4507,6 +4550,7 @@ bool var::isBool() const noexcept { return type->isBool(); } | |||||
| bool var::isDouble() const noexcept { return type->isDouble(); } | bool var::isDouble() const noexcept { return type->isDouble(); } | ||||
| bool var::isString() const noexcept { return type->isString(); } | bool var::isString() const noexcept { return type->isString(); } | ||||
| bool var::isObject() const noexcept { return type->isObject(); } | bool var::isObject() const noexcept { return type->isObject(); } | ||||
| bool var::isArray() const noexcept { return type->isArray(); } | |||||
| bool var::isMethod() const noexcept { return type->isMethod(); } | bool var::isMethod() const noexcept { return type->isMethod(); } | ||||
| var::operator int() const noexcept { return type->toInt (value); } | var::operator int() const noexcept { return type->toInt (value); } | ||||
| @@ -4517,6 +4561,7 @@ var::operator double() const noexcept { return type->toDouble (value); } | |||||
| String var::toString() const { return type->toString (value); } | String var::toString() const { return type->toString (value); } | ||||
| var::operator String() const { return type->toString (value); } | var::operator String() const { return type->toString (value); } | ||||
| ReferenceCountedObject* var::getObject() const noexcept { return type->toObject (value); } | ReferenceCountedObject* var::getObject() const noexcept { return type->toObject (value); } | ||||
| Array<var>* var::getArray() const noexcept { return type->toArray (value); } | |||||
| DynamicObject* var::getDynamicObject() const noexcept { return dynamic_cast <DynamicObject*> (getObject()); } | DynamicObject* var::getDynamicObject() const noexcept { return dynamic_cast <DynamicObject*> (getObject()); } | ||||
| void var::swapWith (var& other) noexcept | void var::swapWith (var& other) noexcept | ||||
| @@ -4533,6 +4578,7 @@ const var& var::operator= (const double newValue) { type->cleanUp (value); typ | |||||
| const var& var::operator= (const char* const newValue) { var v (newValue); swapWith (v); return *this; } | const var& var::operator= (const char* const newValue) { var v (newValue); swapWith (v); return *this; } | ||||
| const var& var::operator= (const wchar_t* const newValue) { var v (newValue); swapWith (v); return *this; } | const var& var::operator= (const wchar_t* const newValue) { var v (newValue); swapWith (v); return *this; } | ||||
| const var& var::operator= (const String& newValue) { var v (newValue); swapWith (v); return *this; } | const var& var::operator= (const String& newValue) { var v (newValue); swapWith (v); return *this; } | ||||
| const var& var::operator= (const Array<var>& newValue) { var v (newValue); swapWith (v); return *this; } | |||||
| const var& var::operator= (ReferenceCountedObject* newValue) { var v (newValue); swapWith (v); return *this; } | const var& var::operator= (ReferenceCountedObject* newValue) { var v (newValue); swapWith (v); return *this; } | ||||
| const var& var::operator= (MethodFunction newValue) { var v (newValue); swapWith (v); return *this; } | const var& var::operator= (MethodFunction newValue) { var v (newValue); swapWith (v); return *this; } | ||||
| @@ -4553,38 +4599,6 @@ bool operator!= (const var& v1, const String& v2) { return v1.toString() != v | |||||
| bool operator== (const var& v1, const char* const v2) { return v1.toString() == v2; } | bool operator== (const var& v1, const char* const v2) { return v1.toString() == v2; } | ||||
| bool operator!= (const var& v1, const char* const v2) { return v1.toString() != v2; } | bool operator!= (const var& v1, const char* const v2) { return v1.toString() != v2; } | ||||
| void var::writeToStream (OutputStream& output) const | |||||
| { | |||||
| type->writeToStream (value, output); | |||||
| } | |||||
| var var::readFromStream (InputStream& input) | |||||
| { | |||||
| const int numBytes = input.readCompressedInt(); | |||||
| if (numBytes > 0) | |||||
| { | |||||
| switch (input.readByte()) | |||||
| { | |||||
| case varMarker_Int: return var (input.readInt()); | |||||
| case varMarker_Int64: return var (input.readInt64()); | |||||
| case varMarker_BoolTrue: return var (true); | |||||
| case varMarker_BoolFalse: return var (false); | |||||
| case varMarker_Double: return var (input.readDouble()); | |||||
| case varMarker_String: | |||||
| { | |||||
| MemoryOutputStream mo; | |||||
| mo.writeFromInputStream (input, numBytes - 1); | |||||
| return var (mo.toUTF8()); | |||||
| } | |||||
| default: input.skipNextBytes (numBytes - 1); break; | |||||
| } | |||||
| } | |||||
| return var::null; | |||||
| } | |||||
| var var::operator[] (const Identifier& propertyName) const | var var::operator[] (const Identifier& propertyName) const | ||||
| { | { | ||||
| DynamicObject* const o = getDynamicObject(); | DynamicObject* const o = getDynamicObject(); | ||||
| @@ -4641,6 +4655,125 @@ var var::call (const Identifier& method, const var& arg1, const var& arg2, const | |||||
| return invoke (method, args, 5); | return invoke (method, args, 5); | ||||
| } | } | ||||
| int var::size() const | |||||
| { | |||||
| const Array<var>* const array = getArray(); | |||||
| return array != nullptr ? array->size() : 0; | |||||
| } | |||||
| const var& var::operator[] (int arrayIndex) const | |||||
| { | |||||
| const Array<var>* const array = getArray(); | |||||
| // When using this method, the var must actually be an array, and the index | |||||
| // must be in-range! | |||||
| jassert (array != nullptr && isPositiveAndBelow (arrayIndex, array->size())); | |||||
| return array->getReference (arrayIndex); | |||||
| } | |||||
| var& var::operator[] (int arrayIndex) | |||||
| { | |||||
| const Array<var>* const array = getArray(); | |||||
| // When using this method, the var must actually be an array, and the index | |||||
| // must be in-range! | |||||
| jassert (array != nullptr && isPositiveAndBelow (arrayIndex, array->size())); | |||||
| return array->getReference (arrayIndex); | |||||
| } | |||||
| Array<var>* var::convertToArray() | |||||
| { | |||||
| Array<var>* array = getArray(); | |||||
| if (array == nullptr) | |||||
| { | |||||
| const Array<var> tempVar; | |||||
| var v (tempVar); | |||||
| array = v.value.arrayValue; | |||||
| if (! isVoid()) | |||||
| array->add (*this); | |||||
| swapWith (v); | |||||
| } | |||||
| return array; | |||||
| } | |||||
| void var::append (const var& value) | |||||
| { | |||||
| convertToArray()->add (value); | |||||
| } | |||||
| void var::remove (const int index) | |||||
| { | |||||
| Array<var>* const array = getArray(); | |||||
| if (array != nullptr) | |||||
| array->remove (index); | |||||
| } | |||||
| void var::insert (const int index, const var& value) | |||||
| { | |||||
| convertToArray()->insert (index, value); | |||||
| } | |||||
| void var::resize (const int numArrayElementsWanted) | |||||
| { | |||||
| convertToArray()->resize (numArrayElementsWanted); | |||||
| } | |||||
| int var::indexOf (const var& value) const | |||||
| { | |||||
| const Array<var>* const array = getArray(); | |||||
| return array != nullptr ? array->indexOf (value) : -1; | |||||
| } | |||||
| void var::writeToStream (OutputStream& output) const | |||||
| { | |||||
| type->writeToStream (value, output); | |||||
| } | |||||
| var var::readFromStream (InputStream& input) | |||||
| { | |||||
| const int numBytes = input.readCompressedInt(); | |||||
| if (numBytes > 0) | |||||
| { | |||||
| switch (input.readByte()) | |||||
| { | |||||
| case varMarker_Int: return var (input.readInt()); | |||||
| case varMarker_Int64: return var (input.readInt64()); | |||||
| case varMarker_BoolTrue: return var (true); | |||||
| case varMarker_BoolFalse: return var (false); | |||||
| case varMarker_Double: return var (input.readDouble()); | |||||
| case varMarker_String: | |||||
| { | |||||
| MemoryOutputStream mo; | |||||
| mo.writeFromInputStream (input, numBytes - 1); | |||||
| return var (mo.toUTF8()); | |||||
| } | |||||
| case varMarker_Array: | |||||
| { | |||||
| var v; | |||||
| Array<var>* const destArray = v.convertToArray(); | |||||
| for (int i = input.readCompressedInt(); --i >= 0;) | |||||
| destArray->add (readFromStream (input)); | |||||
| return v; | |||||
| } | |||||
| default: input.skipNextBytes (numBytes - 1); break; | |||||
| } | |||||
| } | |||||
| return var::null; | |||||
| } | |||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| /*** End of inlined file: juce_Variant.cpp ***/ | /*** End of inlined file: juce_Variant.cpp ***/ | ||||
| @@ -4811,7 +4944,7 @@ const Identifier NamedValueSet::getName (const int index) const | |||||
| return v->name; | return v->name; | ||||
| } | } | ||||
| var NamedValueSet::getValueAt (const int index) const | |||||
| const var& NamedValueSet::getValueAt (const int index) const | |||||
| { | { | ||||
| const NamedValue* const v = values[index]; | const NamedValue* const v = values[index]; | ||||
| jassert (v != nullptr); | jassert (v != nullptr); | ||||
| @@ -8694,6 +8827,20 @@ bool FileOutputStream::write (const void* const src, const int numBytes) | |||||
| return true; | return true; | ||||
| } | } | ||||
| void FileOutputStream::writeRepeatedByte (uint8 byte, int numBytes) | |||||
| { | |||||
| if (bytesInBuffer + numBytes < bufferSize) | |||||
| { | |||||
| memset (buffer + bytesInBuffer, byte, numBytes); | |||||
| bytesInBuffer += numBytes; | |||||
| currentPosition += numBytes; | |||||
| } | |||||
| else | |||||
| { | |||||
| OutputStream::writeRepeatedByte (byte, numBytes); | |||||
| } | |||||
| } | |||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| /*** End of inlined file: juce_FileOutputStream.cpp ***/ | /*** End of inlined file: juce_FileOutputStream.cpp ***/ | ||||
| @@ -10439,15 +10586,19 @@ void MemoryOutputStream::reset() noexcept | |||||
| size = 0; | size = 0; | ||||
| } | } | ||||
| void MemoryOutputStream::prepareToWrite (int numBytes) | |||||
| { | |||||
| const size_t storageNeeded = position + numBytes; | |||||
| if (storageNeeded >= data.getSize()) | |||||
| data.ensureSize ((storageNeeded + jmin ((int) (storageNeeded / 2), 1024 * 1024) + 32) & ~31); | |||||
| } | |||||
| bool MemoryOutputStream::write (const void* const buffer, int howMany) | bool MemoryOutputStream::write (const void* const buffer, int howMany) | ||||
| { | { | ||||
| if (howMany > 0) | if (howMany > 0) | ||||
| { | { | ||||
| const size_t storageNeeded = position + howMany; | |||||
| if (storageNeeded >= data.getSize()) | |||||
| data.ensureSize ((storageNeeded + jmin ((int) (storageNeeded / 2), 1024 * 1024) + 32) & ~31); | |||||
| prepareToWrite (howMany); | |||||
| memcpy (static_cast<char*> (data.getData()) + position, buffer, howMany); | memcpy (static_cast<char*> (data.getData()) + position, buffer, howMany); | ||||
| position += howMany; | position += howMany; | ||||
| size = jmax (size, position); | size = jmax (size, position); | ||||
| @@ -10456,6 +10607,17 @@ bool MemoryOutputStream::write (const void* const buffer, int howMany) | |||||
| return true; | return true; | ||||
| } | } | ||||
| void MemoryOutputStream::writeRepeatedByte (uint8 byte, int howMany) | |||||
| { | |||||
| if (howMany > 0) | |||||
| { | |||||
| prepareToWrite (howMany); | |||||
| memset (static_cast<char*> (data.getData()) + position, byte, howMany); | |||||
| position += howMany; | |||||
| size = jmax (size, position); | |||||
| } | |||||
| } | |||||
| const void* MemoryOutputStream::getData() const noexcept | const void* MemoryOutputStream::getData() const noexcept | ||||
| { | { | ||||
| void* const d = data.getData(); | void* const d = data.getData(); | ||||
| @@ -15618,21 +15780,9 @@ namespace XmlOutputFunctions | |||||
| } | } | ||||
| } | } | ||||
| void writeSpaces (OutputStream& out, int numSpaces) | |||||
| void writeSpaces (OutputStream& out, const int numSpaces) | |||||
| { | { | ||||
| if (numSpaces > 0) | |||||
| { | |||||
| const char blanks[] = " "; | |||||
| const int blankSize = (int) numElementsInArray (blanks) - 1; | |||||
| while (numSpaces > blankSize) | |||||
| { | |||||
| out.write (blanks, blankSize); | |||||
| numSpaces -= blankSize; | |||||
| } | |||||
| out.write (blanks, numSpaces); | |||||
| } | |||||
| out.writeRepeatedByte (' ', numSpaces); | |||||
| } | } | ||||
| } | } | ||||
| @@ -16278,6 +16428,506 @@ END_JUCE_NAMESPACE | |||||
| /*** End of inlined file: juce_XmlElement.cpp ***/ | /*** End of inlined file: juce_XmlElement.cpp ***/ | ||||
| /*** Start of inlined file: juce_JSON.cpp ***/ | |||||
| BEGIN_JUCE_NAMESPACE | |||||
| class JSONParser | |||||
| { | |||||
| public: | |||||
| static Result parseAny (String::CharPointerType& t, var& result) | |||||
| { | |||||
| t = t.findEndOfWhitespace(); | |||||
| String::CharPointerType t2 (t); | |||||
| switch (t2.getAndAdvance()) | |||||
| { | |||||
| case '{': t = t2; return parseObject (t, result); | |||||
| case '[': t = t2; return parseArray (t, result); | |||||
| case '"': t = t2; return parseString (t, result); | |||||
| case '-': | |||||
| t2 = t2.findEndOfWhitespace(); | |||||
| if (! CharacterFunctions::isDigit (*t2)) | |||||
| break; | |||||
| t = t2; | |||||
| return parseNumber (t, result, true); | |||||
| case '0': case '1': case '2': case '3': case '4': | |||||
| case '5': case '6': case '7': case '8': case '9': | |||||
| return parseNumber (t, result, false); | |||||
| case 't': // "true" | |||||
| if (t2.getAndAdvance() == 'r' && t2.getAndAdvance() == 'u' && t2.getAndAdvance() == 'e') | |||||
| { | |||||
| t = t2; | |||||
| result = var (true); | |||||
| return Result::ok(); | |||||
| } | |||||
| break; | |||||
| case 'f': // "false" | |||||
| if (t2.getAndAdvance() == 'a' && t2.getAndAdvance() == 'l' | |||||
| && t2.getAndAdvance() == 's' && t2.getAndAdvance() == 'e') | |||||
| { | |||||
| t = t2; | |||||
| result = var (false); | |||||
| return Result::ok(); | |||||
| } | |||||
| break; | |||||
| case 'n': // "null" | |||||
| if (t2.getAndAdvance() == 'u' && t2.getAndAdvance() == 'l' && t2.getAndAdvance() == 'l') | |||||
| { | |||||
| t = t2; | |||||
| result = var::null; | |||||
| return Result::ok(); | |||||
| } | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| return createFail ("Syntax error", &t); | |||||
| } | |||||
| private: | |||||
| static Result createFail (const char* const message, const String::CharPointerType* location = nullptr) | |||||
| { | |||||
| String m (message); | |||||
| if (location != nullptr) | |||||
| m << ": \"" << String (*location, 20) << '"'; | |||||
| return Result::fail (m); | |||||
| } | |||||
| static Result parseNumber (String::CharPointerType& t, var& result, const bool isNegative) | |||||
| { | |||||
| String::CharPointerType oldT (t); | |||||
| int64 intValue = t.getAndAdvance() - '0'; | |||||
| jassert (intValue >= 0 && intValue < 10); | |||||
| for (;;) | |||||
| { | |||||
| String::CharPointerType previousChar (t); | |||||
| const juce_wchar c = t.getAndAdvance(); | |||||
| const int digit = ((int) c) - '0'; | |||||
| if (isPositiveAndBelow (digit, 10)) | |||||
| { | |||||
| intValue = intValue * 10 + digit; | |||||
| continue; | |||||
| } | |||||
| if (c == 'e' || c == 'E' || c == '.') | |||||
| { | |||||
| t = oldT; | |||||
| const double asDouble = CharacterFunctions::readDoubleValue (t); | |||||
| result = isNegative ? -asDouble : asDouble; | |||||
| return Result::ok(); | |||||
| } | |||||
| if (CharacterFunctions::isWhitespace (c) | |||||
| || c == ',' || c == '}' || c == ']' || c == 0) | |||||
| { | |||||
| t = previousChar; | |||||
| break; | |||||
| } | |||||
| return createFail ("Syntax error in number", &oldT); | |||||
| } | |||||
| const int64 correctedValue = isNegative ? -intValue : intValue; | |||||
| if ((intValue >> 31) != 0) | |||||
| result = correctedValue; | |||||
| else | |||||
| result = (int) correctedValue; | |||||
| return Result::ok(); | |||||
| } | |||||
| static Result parseObject (String::CharPointerType& t, var& result) | |||||
| { | |||||
| DynamicObject* const resultObject = new DynamicObject(); | |||||
| result = resultObject; | |||||
| for (;;) | |||||
| { | |||||
| t = t.findEndOfWhitespace(); | |||||
| String::CharPointerType oldT (t); | |||||
| const juce_wchar c = t.getAndAdvance(); | |||||
| if (c == '}') | |||||
| break; | |||||
| if (c == 0) | |||||
| return createFail ("Unexpected end-of-input in object declaration"); | |||||
| if (c == '"') | |||||
| { | |||||
| var propertyNameVar; | |||||
| Result r (parseString (t, propertyNameVar)); | |||||
| if (r.failed()) | |||||
| return r; | |||||
| const String propertyName (propertyNameVar.toString()); | |||||
| if (propertyName.isNotEmpty()) | |||||
| { | |||||
| t = t.findEndOfWhitespace(); | |||||
| oldT = t; | |||||
| const juce_wchar c = t.getAndAdvance(); | |||||
| if (c != ':') | |||||
| return createFail ("Expected ':', but found", &oldT); | |||||
| var propertyValue; | |||||
| Result r (parseAny (t, propertyValue)); | |||||
| if (r.failed()) | |||||
| return r; | |||||
| resultObject->setProperty (propertyName, propertyValue); | |||||
| t = t.findEndOfWhitespace(); | |||||
| oldT = t; | |||||
| const juce_wchar nextChar = t.getAndAdvance(); | |||||
| if (nextChar == ',') | |||||
| continue; | |||||
| else if (nextChar == '}') | |||||
| break; | |||||
| } | |||||
| } | |||||
| return createFail ("Expected object member declaration, but found", &oldT); | |||||
| } | |||||
| return Result::ok(); | |||||
| } | |||||
| static Result parseArray (String::CharPointerType& t, var& result) | |||||
| { | |||||
| result = var (Array<var>()); | |||||
| Array<var>* const destArray = result.getArray(); | |||||
| for (;;) | |||||
| { | |||||
| t = t.findEndOfWhitespace(); | |||||
| String::CharPointerType oldT (t); | |||||
| const juce_wchar c = t.getAndAdvance(); | |||||
| if (c == ']') | |||||
| break; | |||||
| if (c == 0) | |||||
| return createFail ("Unexpected end-of-input in array declaration"); | |||||
| t = oldT; | |||||
| destArray->add (var::null); | |||||
| Result r (parseAny (t, destArray->getReference (destArray->size() - 1))); | |||||
| if (r.failed()) | |||||
| return r; | |||||
| t = t.findEndOfWhitespace(); | |||||
| oldT = t; | |||||
| const juce_wchar nextChar = t.getAndAdvance(); | |||||
| if (nextChar == ',') | |||||
| continue; | |||||
| else if (nextChar == ']') | |||||
| break; | |||||
| return createFail ("Expected object array item, but found", &oldT); | |||||
| } | |||||
| return Result::ok(); | |||||
| } | |||||
| static Result parseString (String::CharPointerType& t, var& result) | |||||
| { | |||||
| Array<juce_wchar> buffer; | |||||
| buffer.ensureStorageAllocated (256); | |||||
| for (;;) | |||||
| { | |||||
| juce_wchar c = t.getAndAdvance(); | |||||
| if (c == '"') | |||||
| break; | |||||
| if (c == '\\') | |||||
| { | |||||
| c = t.getAndAdvance(); | |||||
| switch (c) | |||||
| { | |||||
| case '"': | |||||
| case '\\': | |||||
| case '/': break; | |||||
| case 'b': c = '\b'; break; | |||||
| case 'f': c = '\f'; break; | |||||
| case 'n': c = '\n'; break; | |||||
| case 'r': c = '\r'; break; | |||||
| case 't': c = '\t'; break; | |||||
| case 'u': | |||||
| { | |||||
| c = 0; | |||||
| for (int i = 4; --i >= 0;) | |||||
| { | |||||
| const int digitValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance()); | |||||
| if (digitValue < 0) | |||||
| return createFail ("Syntax error in unicode escape sequence"); | |||||
| c = (juce_wchar) ((c << 4) + digitValue); | |||||
| } | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| if (c == 0) | |||||
| return createFail ("Unexpected end-of-input in string constant"); | |||||
| buffer.add (c); | |||||
| } | |||||
| buffer.add (0); | |||||
| result = String (CharPointer_UTF32 (buffer.getRawDataPointer())); | |||||
| return Result::ok(); | |||||
| } | |||||
| }; | |||||
| class JSONFormatter | |||||
| { | |||||
| public: | |||||
| static void write (OutputStream& out, const var& v, | |||||
| const int indentLevel, const bool allOnOneLine) | |||||
| { | |||||
| if (v.isString()) | |||||
| { | |||||
| writeString (out, v.toString().getCharPointer()); | |||||
| } | |||||
| else if (v.isVoid()) | |||||
| { | |||||
| out << "null"; | |||||
| } | |||||
| else if (v.isBool()) | |||||
| { | |||||
| out << (static_cast<bool> (v) ? "true" : "false"); | |||||
| } | |||||
| else if (v.isArray()) | |||||
| { | |||||
| writeArray (out, *v.getArray(), indentLevel, allOnOneLine); | |||||
| } | |||||
| else if (v.isObject()) | |||||
| { | |||||
| DynamicObject* object = dynamic_cast<DynamicObject*> (v.getObject()); | |||||
| jassert (object != nullptr); // Only DynamicObjects can be converted to JSON! | |||||
| writeObject (out, *object, indentLevel, allOnOneLine); | |||||
| } | |||||
| else | |||||
| { | |||||
| jassert (! v.isMethod()); // Can't convert an object with methods to JSON! | |||||
| out << v.toString(); | |||||
| } | |||||
| } | |||||
| private: | |||||
| enum { indentSize = 2 }; | |||||
| static void writeEscapedChar (OutputStream& out, const unsigned short value) | |||||
| { | |||||
| out << "\\u" << String::toHexString ((int) value).paddedLeft ('0', 4); | |||||
| } | |||||
| static void writeString (OutputStream& out, String::CharPointerType t) | |||||
| { | |||||
| out << '"'; | |||||
| for (;;) | |||||
| { | |||||
| const juce_wchar c (t.getAndAdvance()); | |||||
| switch (c) | |||||
| { | |||||
| case 0: out << '"'; return; | |||||
| case '\"': out << "\\\""; break; | |||||
| case '\\': out << "\\\\"; break; | |||||
| case '\b': out << "\\b"; break; | |||||
| case '\f': out << "\\f"; break; | |||||
| case '\t': out << "\\t"; break; | |||||
| case '\r': out << "\\r"; break; | |||||
| case '\n': out << "\\n"; break; | |||||
| default: | |||||
| if (c >= 32 && c < 127) | |||||
| { | |||||
| out << (char) c; | |||||
| } | |||||
| else | |||||
| { | |||||
| if (CharPointer_UTF16::getBytesRequiredFor (c) > 2) | |||||
| { | |||||
| CharPointer_UTF16::CharType chars[2]; | |||||
| CharPointer_UTF16 utf16 (chars); | |||||
| utf16.write (c); | |||||
| for (int i = 0; i < 2; ++i) | |||||
| writeEscapedChar (out, (unsigned short) chars[i]); | |||||
| } | |||||
| else | |||||
| { | |||||
| writeEscapedChar (out, (unsigned short) c); | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| static void writeSpaces (OutputStream& out, int numSpaces) | |||||
| { | |||||
| out.writeRepeatedByte (' ', numSpaces); | |||||
| } | |||||
| static void writeArray (OutputStream& out, const Array<var>& array, | |||||
| const int indentLevel, const bool allOnOneLine) | |||||
| { | |||||
| out << '['; | |||||
| if (! allOnOneLine) | |||||
| out << newLine; | |||||
| for (int i = 0; i < array.size(); ++i) | |||||
| { | |||||
| if (! allOnOneLine) | |||||
| writeSpaces (out, indentLevel + indentSize); | |||||
| write (out, array.getReference(i), indentLevel + indentSize, allOnOneLine); | |||||
| if (i < array.size() - 1) | |||||
| { | |||||
| if (allOnOneLine) | |||||
| out << ", "; | |||||
| else | |||||
| out << ',' << newLine; | |||||
| } | |||||
| else if (! allOnOneLine) | |||||
| out << newLine; | |||||
| } | |||||
| if (! allOnOneLine) | |||||
| writeSpaces (out, indentLevel); | |||||
| out << ']'; | |||||
| } | |||||
| static void writeObject (OutputStream& out, DynamicObject& object, | |||||
| const int indentLevel, const bool allOnOneLine) | |||||
| { | |||||
| NamedValueSet& props = object.getProperties(); | |||||
| out << '{'; | |||||
| if (! allOnOneLine) | |||||
| out << newLine; | |||||
| LinkedListPointer<NamedValueSet::NamedValue>* i = &(props.values); | |||||
| for (;;) | |||||
| { | |||||
| NamedValueSet::NamedValue* const v = i->get(); | |||||
| if (v == nullptr) | |||||
| break; | |||||
| if (! allOnOneLine) | |||||
| writeSpaces (out, indentLevel + indentSize); | |||||
| writeString (out, v->name); | |||||
| out << ": "; | |||||
| write (out, v->value, indentLevel + indentSize, allOnOneLine); | |||||
| if (v->nextListItem.get() != nullptr) | |||||
| { | |||||
| if (allOnOneLine) | |||||
| out << ", "; | |||||
| else | |||||
| out << ',' << newLine; | |||||
| } | |||||
| else if (! allOnOneLine) | |||||
| out << newLine; | |||||
| i = &(v->nextListItem); | |||||
| } | |||||
| if (! allOnOneLine) | |||||
| writeSpaces (out, indentLevel); | |||||
| out << '}'; | |||||
| } | |||||
| }; | |||||
| var JSON::parse (const String& text) | |||||
| { | |||||
| var result; | |||||
| String::CharPointerType t (text.getCharPointer()); | |||||
| if (! JSONParser::parseAny (t, result)) | |||||
| result = var::null; | |||||
| return result; | |||||
| } | |||||
| var JSON::parse (InputStream& input) | |||||
| { | |||||
| return parse (input.readEntireStreamAsString()); | |||||
| } | |||||
| var JSON::parse (const File& file) | |||||
| { | |||||
| return parse (file.loadFileAsString()); | |||||
| } | |||||
| Result JSON::parse (const String& text, var& result) | |||||
| { | |||||
| String::CharPointerType t (text.getCharPointer()); | |||||
| return JSONParser::parseAny (t, result); | |||||
| } | |||||
| String JSON::toString (const var& data, const bool allOnOneLine) | |||||
| { | |||||
| MemoryOutputStream mo (1024); | |||||
| JSONFormatter::write (mo, data, 0, allOnOneLine); | |||||
| return mo.toString(); | |||||
| } | |||||
| void JSON::writeToStream (OutputStream& output, const var& data, const bool allOnOneLine) | |||||
| { | |||||
| JSONFormatter::write (output, data, 0, allOnOneLine); | |||||
| } | |||||
| END_JUCE_NAMESPACE | |||||
| /*** End of inlined file: juce_JSON.cpp ***/ | |||||
| /*** Start of inlined file: juce_ReadWriteLock.cpp ***/ | /*** Start of inlined file: juce_ReadWriteLock.cpp ***/ | ||||
| BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
| @@ -243958,11 +244608,11 @@ bool SystemStats::isOperatingSystem64Bit() | |||||
| #else | #else | ||||
| typedef BOOL (WINAPI* LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); | typedef BOOL (WINAPI* LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); | ||||
| LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress (GetModuleHandle (L"kernel32"), "IsWow64Process"); | |||||
| LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress (GetModuleHandle (_T("kernel32")), "IsWow64Process"); | |||||
| BOOL isWow64 = FALSE; | BOOL isWow64 = FALSE; | ||||
| return (fnIsWow64Process != 0) | |||||
| return fnIsWow64Process != 0 | |||||
| && fnIsWow64Process (GetCurrentProcess(), &isWow64) | && fnIsWow64Process (GetCurrentProcess(), &isWow64) | ||||
| && (isWow64 != FALSE); | && (isWow64 != FALSE); | ||||
| #endif | #endif | ||||
| @@ -246073,14 +246723,8 @@ void PlatformUtilities::registerFileAssociation (const String& fileExtension, | |||||
| bool juce_IsRunningInWine() | bool juce_IsRunningInWine() | ||||
| { | { | ||||
| HKEY key; | |||||
| if (RegOpenKeyEx (HKEY_CURRENT_USER, _T("Software\\Wine"), 0, KEY_READ, &key) == ERROR_SUCCESS) | |||||
| { | |||||
| RegCloseKey (key); | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| HMODULE ntdll = GetModuleHandle (_T("ntdll.dll")); | |||||
| return ntdll != 0 && GetProcAddress (ntdll, "wine_get_version") != 0; | |||||
| } | } | ||||
| const String JUCE_CALLTYPE PlatformUtilities::getCurrentCommandLineParams() | const String JUCE_CALLTYPE PlatformUtilities::getCurrentCommandLineParams() | ||||
| @@ -249045,6 +249689,14 @@ private: | |||||
| #endif | #endif | ||||
| } | } | ||||
| static int getMinTimeBetweenMouseMoves() | |||||
| { | |||||
| if (SystemStats::getOperatingSystemType() >= SystemStats::WinVista) | |||||
| return 0; | |||||
| return 1000 / 60; // Throttling the incoming mouse-events seems to still be needed in XP.. | |||||
| } | |||||
| void doMouseMove (const Point<int>& position) | void doMouseMove (const Point<int>& position) | ||||
| { | { | ||||
| if (! isMouseOver) | if (! isMouseOver) | ||||
| @@ -249069,12 +249721,11 @@ private: | |||||
| return; | return; | ||||
| } | } | ||||
| // (Throttling the incoming queue of mouse-events seems to still be required in XP..) | |||||
| static uint32 lastMouseTime = 0; | static uint32 lastMouseTime = 0; | ||||
| static int minTimeBetweenMouses = getMinTimeBetweenMouseMoves(); | |||||
| const uint32 now = Time::getMillisecondCounter(); | const uint32 now = Time::getMillisecondCounter(); | ||||
| const int maxMouseMovesPerSecond = 60; | |||||
| if (now > lastMouseTime + 1000 / maxMouseMovesPerSecond) | |||||
| if (now >= lastMouseTime + minTimeBetweenMouses) | |||||
| { | { | ||||
| lastMouseTime = now; | lastMouseTime = now; | ||||
| doMouseEvent (position); | doMouseEvent (position); | ||||
| @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 53 | #define JUCE_MINOR_VERSION 53 | ||||
| #define JUCE_BUILDNUMBER 97 | |||||
| #define JUCE_BUILDNUMBER 98 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -7908,7 +7908,7 @@ public: | |||||
| /** Checks a given string for characters that might not be valid in an Identifier. | /** Checks a given string for characters that might not be valid in an Identifier. | ||||
| Since Identifiers are used as a script variables and XML attributes, they should only contain | Since Identifiers are used as a script variables and XML attributes, they should only contain | ||||
| alphanumeric characters and underscores. | |||||
| alphanumeric characters, underscores, or the '-' and ':' characters. | |||||
| */ | */ | ||||
| static bool isValidIdentifier (const String& possibleIdentifier) noexcept; | static bool isValidIdentifier (const String& possibleIdentifier) noexcept; | ||||
| @@ -8496,6 +8496,7 @@ public: | |||||
| var (const char* value); | var (const char* value); | ||||
| var (const wchar_t* value); | var (const wchar_t* value); | ||||
| var (const String& value); | var (const String& value); | ||||
| var (const Array<var>& value); | |||||
| var (ReferenceCountedObject* object); | var (ReferenceCountedObject* object); | ||||
| var (MethodFunction method) noexcept; | var (MethodFunction method) noexcept; | ||||
| @@ -8507,6 +8508,7 @@ public: | |||||
| const var& operator= (const char* value); | const var& operator= (const char* value); | ||||
| const var& operator= (const wchar_t* value); | const var& operator= (const wchar_t* value); | ||||
| const var& operator= (const String& value); | const var& operator= (const String& value); | ||||
| const var& operator= (const Array<var>& value); | |||||
| const var& operator= (ReferenceCountedObject* object); | const var& operator= (ReferenceCountedObject* object); | ||||
| const var& operator= (MethodFunction method); | const var& operator= (MethodFunction method); | ||||
| @@ -8519,6 +8521,7 @@ public: | |||||
| operator double() const noexcept; | operator double() const noexcept; | ||||
| operator String() const; | operator String() const; | ||||
| String toString() const; | String toString() const; | ||||
| Array<var>* getArray() const noexcept; | |||||
| ReferenceCountedObject* getObject() const noexcept; | ReferenceCountedObject* getObject() const noexcept; | ||||
| DynamicObject* getDynamicObject() const noexcept; | DynamicObject* getDynamicObject() const noexcept; | ||||
| @@ -8529,18 +8532,83 @@ public: | |||||
| bool isDouble() const noexcept; | bool isDouble() const noexcept; | ||||
| bool isString() const noexcept; | bool isString() const noexcept; | ||||
| bool isObject() const noexcept; | bool isObject() const noexcept; | ||||
| bool isArray() const noexcept; | |||||
| bool isMethod() const noexcept; | bool isMethod() const noexcept; | ||||
| /** Writes a binary representation of this value to a stream. | |||||
| The data can be read back later using readFromStream(). | |||||
| /** Returns true if this var has the same value as the one supplied. | |||||
| Note that this ignores the type, so a string var "123" and an integer var with the | |||||
| value 123 are considered to be equal. | |||||
| @see equalsWithSameType | |||||
| */ | */ | ||||
| void writeToStream (OutputStream& output) const; | |||||
| bool equals (const var& other) const noexcept; | |||||
| /** Reads back a stored binary representation of a value. | |||||
| The data in the stream must have been written using writeToStream(), or this | |||||
| will have unpredictable results. | |||||
| /** Returns true if this var has the same value and type as the one supplied. | |||||
| This differs from equals() because e.g. "123" and 123 will be considered different. | |||||
| @see equals | |||||
| */ | */ | ||||
| static var readFromStream (InputStream& input); | |||||
| bool equalsWithSameType (const var& other) const noexcept; | |||||
| /** If the var is an array, this returns the number of elements. | |||||
| If the var isn't actually an array, this will return 0. | |||||
| */ | |||||
| int size() const; | |||||
| /** If the var is an array, this can be used to return one of its elements. | |||||
| To call this method, you must make sure that the var is actually an array, and | |||||
| that the index is a valid number. If these conditions aren't met, behaviour is | |||||
| undefined. | |||||
| For more control over the array's contents, you can call getArray() and manipulate | |||||
| it directly as an Array<var>. | |||||
| */ | |||||
| const var& operator[] (int arrayIndex) const; | |||||
| /** If the var is an array, this can be used to return one of its elements. | |||||
| To call this method, you must make sure that the var is actually an array, and | |||||
| that the index is a valid number. If these conditions aren't met, behaviour is | |||||
| undefined. | |||||
| For more control over the array's contents, you can call getArray() and manipulate | |||||
| it directly as an Array<var>. | |||||
| */ | |||||
| var& operator[] (int arrayIndex); | |||||
| /** Appends an element to the var, converting it to an array if it isn't already one. | |||||
| If the var isn't an array, it will be converted to one, and if its value was non-void, | |||||
| this value will be kept as the first element of the new array. The parameter value | |||||
| will then be appended to it. | |||||
| For more control over the array's contents, you can call getArray() and manipulate | |||||
| it directly as an Array<var>. | |||||
| */ | |||||
| void append (const var& valueToAppend); | |||||
| /** Inserts an element to the var, converting it to an array if it isn't already one. | |||||
| If the var isn't an array, it will be converted to one, and if its value was non-void, | |||||
| this value will be kept as the first element of the new array. The parameter value | |||||
| will then be inserted into it. | |||||
| For more control over the array's contents, you can call getArray() and manipulate | |||||
| it directly as an Array<var>. | |||||
| */ | |||||
| void insert (int index, const var& value); | |||||
| /** If the var is an array, this removes one of its elements. | |||||
| If the index is out-of-range or the var isn't an array, nothing will be done. | |||||
| For more control over the array's contents, you can call getArray() and manipulate | |||||
| it directly as an Array<var>. | |||||
| */ | |||||
| void remove (int index); | |||||
| /** Treating the var as an array, this resizes it to contain the specified number of elements. | |||||
| If the var isn't an array, it will be converted to one, and if its value was non-void, | |||||
| this value will be kept as the first element of the new array before resizing. | |||||
| For more control over the array's contents, you can call getArray() and manipulate | |||||
| it directly as an Array<var>. | |||||
| */ | |||||
| void resize (int numArrayElementsWanted); | |||||
| /** If the var is an array, this searches it for the first occurrence of the specified value, | |||||
| and returns its index. | |||||
| If the var isn't an array, or if the value isn't found, this returns -1. | |||||
| */ | |||||
| int indexOf (const var& value) const; | |||||
| /** If this variant is an object, this returns one of its properties. */ | /** If this variant is an object, this returns one of its properties. */ | ||||
| var operator[] (const Identifier& propertyName) const; | var operator[] (const Identifier& propertyName) const; | ||||
| @@ -8560,18 +8628,16 @@ public: | |||||
| /** If this variant is an object, this invokes one of its methods with a list of arguments. */ | /** If this variant is an object, this invokes one of its methods with a list of arguments. */ | ||||
| var invoke (const Identifier& method, const var* arguments, int numArguments) const; | var invoke (const Identifier& method, const var* arguments, int numArguments) const; | ||||
| /** Returns true if this var has the same value as the one supplied. | |||||
| Note that this ignores the type, so a string var "123" and an integer var with the | |||||
| value 123 are considered to be equal. | |||||
| @see equalsWithSameType | |||||
| /** Writes a binary representation of this value to a stream. | |||||
| The data can be read back later using readFromStream(). | |||||
| */ | */ | ||||
| bool equals (const var& other) const noexcept; | |||||
| void writeToStream (OutputStream& output) const; | |||||
| /** Returns true if this var has the same value and type as the one supplied. | |||||
| This differs from equals() because e.g. "123" and 123 will be considered different. | |||||
| @see equals | |||||
| /** Reads back a stored binary representation of a value. | |||||
| The data in the stream must have been written using writeToStream(), or this | |||||
| will have unpredictable results. | |||||
| */ | */ | ||||
| bool equalsWithSameType (const var& other) const noexcept; | |||||
| static var readFromStream (InputStream& input); | |||||
| private: | private: | ||||
| @@ -8583,6 +8649,7 @@ private: | |||||
| class VariantType_Bool; friend class VariantType_Bool; | class VariantType_Bool; friend class VariantType_Bool; | ||||
| class VariantType_String; friend class VariantType_String; | class VariantType_String; friend class VariantType_String; | ||||
| class VariantType_Object; friend class VariantType_Object; | class VariantType_Object; friend class VariantType_Object; | ||||
| class VariantType_Array; friend class VariantType_Array; | |||||
| class VariantType_Method; friend class VariantType_Method; | class VariantType_Method; friend class VariantType_Method; | ||||
| union ValueUnion | union ValueUnion | ||||
| @@ -8593,12 +8660,14 @@ private: | |||||
| double doubleValue; | double doubleValue; | ||||
| char stringValue [sizeof (String)]; | char stringValue [sizeof (String)]; | ||||
| ReferenceCountedObject* objectValue; | ReferenceCountedObject* objectValue; | ||||
| Array<var>* arrayValue; | |||||
| MethodFunction methodValue; | MethodFunction methodValue; | ||||
| }; | }; | ||||
| const VariantType* type; | const VariantType* type; | ||||
| ValueUnion value; | ValueUnion value; | ||||
| Array<var>* convertToArray(); | |||||
| friend class DynamicObject; | friend class DynamicObject; | ||||
| var invokeMethod (DynamicObject*, const var*, int) const; | var invokeMethod (DynamicObject*, const var*, int) const; | ||||
| }; | }; | ||||
| @@ -8938,6 +9007,9 @@ private: | |||||
| /*** End of inlined file: juce_LinkedListPointer.h ***/ | /*** End of inlined file: juce_LinkedListPointer.h ***/ | ||||
| class XmlElement; | class XmlElement; | ||||
| #ifndef DOXYGEN | |||||
| class JSONFormatter; | |||||
| #endif | |||||
| /** Holds a set of named var objects. | /** Holds a set of named var objects. | ||||
| @@ -8999,7 +9071,7 @@ public: | |||||
| /** Returns the value of the item at a given index. | /** Returns the value of the item at a given index. | ||||
| The index must be between 0 and size() - 1. | The index must be between 0 and size() - 1. | ||||
| */ | */ | ||||
| var getValueAt (int index) const; | |||||
| const var& getValueAt (int index) const; | |||||
| /** Removes all values. */ | /** Removes all values. */ | ||||
| void clear(); | void clear(); | ||||
| @@ -9041,6 +9113,8 @@ private: | |||||
| friend class LinkedListPointer<NamedValue>; | friend class LinkedListPointer<NamedValue>; | ||||
| LinkedListPointer<NamedValue> values; | LinkedListPointer<NamedValue> values; | ||||
| friend class JSONFormatter; | |||||
| }; | }; | ||||
| #endif // __JUCE_NAMEDVALUESET_JUCEHEADER__ | #endif // __JUCE_NAMEDVALUESET_JUCEHEADER__ | ||||
| @@ -9439,6 +9513,9 @@ public: | |||||
| /** Removes all properties and methods from the object. */ | /** Removes all properties and methods from the object. */ | ||||
| void clear(); | void clear(); | ||||
| /** Returns the NamedValueSet that holds the object's properties. */ | |||||
| NamedValueSet& getProperties() noexcept { return properties; } | |||||
| private: | private: | ||||
| NamedValueSet properties; | NamedValueSet properties; | ||||
| @@ -19285,6 +19362,7 @@ public: | |||||
| int64 getPosition(); | int64 getPosition(); | ||||
| bool setPosition (int64 pos); | bool setPosition (int64 pos); | ||||
| bool write (const void* data, int numBytes); | bool write (const void* data, int numBytes); | ||||
| void writeRepeatedByte (uint8 byte, int numTimesToRepeat); | |||||
| private: | private: | ||||
| @@ -21122,6 +21200,7 @@ public: | |||||
| int64 getPosition() { return position; } | int64 getPosition() { return position; } | ||||
| bool setPosition (int64 newPosition); | bool setPosition (int64 newPosition); | ||||
| int writeFromInputStream (InputStream& source, int64 maxNumBytesToWrite); | int writeFromInputStream (InputStream& source, int64 maxNumBytesToWrite); | ||||
| void writeRepeatedByte (uint8 byte, int numTimesToRepeat); | |||||
| private: | private: | ||||
| @@ -21130,6 +21209,7 @@ private: | |||||
| size_t position, size; | size_t position, size; | ||||
| void trimExternalBlockSize(); | void trimExternalBlockSize(); | ||||
| void prepareToWrite (int numBytes); | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryOutputStream); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryOutputStream); | ||||
| }; | }; | ||||
| @@ -21802,6 +21882,98 @@ private: | |||||
| #endif | #endif | ||||
| #ifndef __JUCE_IDENTIFIER_JUCEHEADER__ | #ifndef __JUCE_IDENTIFIER_JUCEHEADER__ | ||||
| #endif | |||||
| #ifndef __JUCE_JSON_JUCEHEADER__ | |||||
| /*** Start of inlined file: juce_JSON.h ***/ | |||||
| #ifndef __JUCE_JSON_JUCEHEADER__ | |||||
| #define __JUCE_JSON_JUCEHEADER__ | |||||
| class InputStream; | |||||
| class OutputStream; | |||||
| class File; | |||||
| /** | |||||
| Contains static methods for converting JSON-formatted text to and from var objects. | |||||
| The var class is structurally compatible with JSON-formatted data, so these | |||||
| functions allow you to parse JSON into a var object, and to convert a var | |||||
| object to JSON-formatted text. | |||||
| @see var | |||||
| */ | |||||
| class JSON | |||||
| { | |||||
| public: | |||||
| /** Parses a string of JSON-formatted text, and returns a result code containing | |||||
| any parse errors. | |||||
| This will return the parsed structure in the parsedResult parameter, and will | |||||
| return a Result object to indicate whether parsing was successful, and if not, | |||||
| it will contain an error message. | |||||
| If you're not interested in the error message, you can use one of the other | |||||
| shortcut parse methods, which simply return a var::null if the parsing fails. | |||||
| */ | |||||
| static Result parse (const String& text, var& parsedResult); | |||||
| /** Attempts to parse some JSON-formatted text, and returns the result as a var object. | |||||
| If the parsing fails, this simply returns var::null - if you need to find out more | |||||
| detail about the parse error, use the alternative parse() method which returns a Result. | |||||
| */ | |||||
| static var parse (const String& text); | |||||
| /** Attempts to parse some JSON-formatted text from a file, and returns the result | |||||
| as a var object. | |||||
| Note that this is just a short-cut for reading the entire file into a string and | |||||
| parsing the result. | |||||
| If the parsing fails, this simply returns var::null - if you need to find out more | |||||
| detail about the parse error, use the alternative parse() method which returns a Result. | |||||
| */ | |||||
| static var parse (const File& file); | |||||
| /** Attempts to parse some JSON-formatted text from a stream, and returns the result | |||||
| as a var object. | |||||
| Note that this is just a short-cut for reading the entire stream into a string and | |||||
| parsing the result. | |||||
| If the parsing fails, this simply returns var::null - if you need to find out more | |||||
| detail about the parse error, use the alternative parse() method which returns a Result. | |||||
| */ | |||||
| static var parse (InputStream& input); | |||||
| /** Returns a string which contains a JSON-formatted representation of the var object. | |||||
| If allOnOneLine is true, the result will be compacted into a single line of text | |||||
| with no carriage-returns. If false, it will be laid-out in a more human-readable format. | |||||
| @see writeToStream | |||||
| */ | |||||
| static String toString (const var& objectToFormat, | |||||
| bool allOnOneLine = false); | |||||
| /** Writes a JSON-formatted representation of the var object to the given stream. | |||||
| If allOnOneLine is true, the result will be compacted into a single line of text | |||||
| with no carriage-returns. If false, it will be laid-out in a more human-readable format. | |||||
| @see toString | |||||
| */ | |||||
| static void writeToStream (OutputStream& output, | |||||
| const var& objectToFormat, | |||||
| bool allOnOneLine = false); | |||||
| private: | |||||
| JSON(); // This class can't be instantiated - just use its static methods. | |||||
| }; | |||||
| #endif // __JUCE_JSON_JUCEHEADER__ | |||||
| /*** End of inlined file: juce_JSON.h ***/ | |||||
| #endif | #endif | ||||
| #ifndef __JUCE_LOCALISEDSTRINGS_JUCEHEADER__ | #ifndef __JUCE_LOCALISEDSTRINGS_JUCEHEADER__ | ||||
| @@ -29,6 +29,9 @@ | |||||
| #include "juce_Variant.h" | #include "juce_Variant.h" | ||||
| #include "../containers/juce_LinkedListPointer.h" | #include "../containers/juce_LinkedListPointer.h" | ||||
| class XmlElement; | class XmlElement; | ||||
| #ifndef DOXYGEN | |||||
| class JSONFormatter; | |||||
| #endif | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -137,6 +140,8 @@ private: | |||||
| friend class LinkedListPointer<NamedValue>; | friend class LinkedListPointer<NamedValue>; | ||||
| LinkedListPointer<NamedValue> values; | LinkedListPointer<NamedValue> values; | ||||
| friend class JSONFormatter; | |||||
| }; | }; | ||||
| @@ -38,7 +38,8 @@ enum VariantStreamMarkers | |||||
| varMarker_BoolFalse = 3, | varMarker_BoolFalse = 3, | ||||
| varMarker_Double = 4, | varMarker_Double = 4, | ||||
| varMarker_String = 5, | varMarker_String = 5, | ||||
| varMarker_Int64 = 6 | |||||
| varMarker_Int64 = 6, | |||||
| varMarker_Array = 7 | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -54,6 +55,7 @@ public: | |||||
| virtual String toString (const ValueUnion&) const { return String::empty; } | virtual String toString (const ValueUnion&) const { return String::empty; } | ||||
| virtual bool toBool (const ValueUnion&) const noexcept { return false; } | virtual bool toBool (const ValueUnion&) const noexcept { return false; } | ||||
| virtual ReferenceCountedObject* toObject (const ValueUnion&) const noexcept { return nullptr; } | virtual ReferenceCountedObject* toObject (const ValueUnion&) const noexcept { return nullptr; } | ||||
| virtual Array<var>* toArray (const ValueUnion&) const noexcept { return 0; } | |||||
| virtual bool isVoid() const noexcept { return false; } | virtual bool isVoid() const noexcept { return false; } | ||||
| virtual bool isInt() const noexcept { return false; } | virtual bool isInt() const noexcept { return false; } | ||||
| @@ -62,6 +64,7 @@ public: | |||||
| virtual bool isDouble() const noexcept { return false; } | virtual bool isDouble() const noexcept { return false; } | ||||
| virtual bool isString() const noexcept { return false; } | virtual bool isString() const noexcept { return false; } | ||||
| virtual bool isObject() const noexcept { return false; } | virtual bool isObject() const noexcept { return false; } | ||||
| virtual bool isArray() const noexcept { return false; } | |||||
| virtual bool isMethod() const noexcept { return false; } | virtual bool isMethod() const noexcept { return false; } | ||||
| virtual void cleanUp (ValueUnion&) const noexcept {} | virtual void cleanUp (ValueUnion&) const noexcept {} | ||||
| @@ -256,6 +259,41 @@ public: | |||||
| } | } | ||||
| }; | }; | ||||
| //============================================================================== | |||||
| class var::VariantType_Array : public var::VariantType | |||||
| { | |||||
| public: | |||||
| VariantType_Array() noexcept {} | |||||
| static const VariantType_Array instance; | |||||
| void cleanUp (ValueUnion& data) const noexcept { delete data.arrayValue; } | |||||
| void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.arrayValue = new Array<var> (*(source.arrayValue)); } | |||||
| String toString (const ValueUnion&) const { return "[Array]"; } | |||||
| bool isArray() const noexcept { return true; } | |||||
| Array<var>* toArray (const ValueUnion& data) const noexcept { return data.arrayValue; } | |||||
| bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept | |||||
| { | |||||
| const Array<var>* const otherArray = otherType.toArray (otherData); | |||||
| return otherArray != nullptr && *otherArray == *(data.arrayValue); | |||||
| } | |||||
| void writeToStream (const ValueUnion& data, OutputStream& output) const | |||||
| { | |||||
| MemoryOutputStream buffer (512); | |||||
| const int numItems = data.arrayValue->size(); | |||||
| buffer.writeCompressedInt (numItems); | |||||
| for (int i = 0; i < numItems; ++i) | |||||
| data.arrayValue->getReference(i).writeToStream (buffer); | |||||
| output.writeCompressedInt (1 + buffer.getDataSize()); | |||||
| output.writeByte (varMarker_Array); | |||||
| output << buffer; | |||||
| } | |||||
| }; | |||||
| //============================================================================== | //============================================================================== | ||||
| class var::VariantType_Method : public var::VariantType | class var::VariantType_Method : public var::VariantType | ||||
| { | { | ||||
| @@ -287,6 +325,7 @@ const var::VariantType_Bool var::VariantType_Bool::instance; | |||||
| const var::VariantType_Double var::VariantType_Double::instance; | const var::VariantType_Double var::VariantType_Double::instance; | ||||
| const var::VariantType_String var::VariantType_String::instance; | const var::VariantType_String var::VariantType_String::instance; | ||||
| const var::VariantType_Object var::VariantType_Object::instance; | const var::VariantType_Object var::VariantType_Object::instance; | ||||
| const var::VariantType_Array var::VariantType_Array::instance; | |||||
| const var::VariantType_Method var::VariantType_Method::instance; | const var::VariantType_Method var::VariantType_Method::instance; | ||||
| @@ -343,6 +382,11 @@ var::var (const wchar_t* const value_) : type (&VariantType_String::instance) | |||||
| new (value.stringValue) String (value_); | new (value.stringValue) String (value_); | ||||
| } | } | ||||
| var::var (const Array<var>& value_) : type (&VariantType_Array::instance) | |||||
| { | |||||
| value.arrayValue = new Array<var> (value_); | |||||
| } | |||||
| var::var (ReferenceCountedObject* const object) : type (&VariantType_Object::instance) | var::var (ReferenceCountedObject* const object) : type (&VariantType_Object::instance) | ||||
| { | { | ||||
| value.objectValue = object; | value.objectValue = object; | ||||
| @@ -364,6 +408,7 @@ bool var::isBool() const noexcept { return type->isBool(); } | |||||
| bool var::isDouble() const noexcept { return type->isDouble(); } | bool var::isDouble() const noexcept { return type->isDouble(); } | ||||
| bool var::isString() const noexcept { return type->isString(); } | bool var::isString() const noexcept { return type->isString(); } | ||||
| bool var::isObject() const noexcept { return type->isObject(); } | bool var::isObject() const noexcept { return type->isObject(); } | ||||
| bool var::isArray() const noexcept { return type->isArray(); } | |||||
| bool var::isMethod() const noexcept { return type->isMethod(); } | bool var::isMethod() const noexcept { return type->isMethod(); } | ||||
| var::operator int() const noexcept { return type->toInt (value); } | var::operator int() const noexcept { return type->toInt (value); } | ||||
| @@ -374,6 +419,7 @@ var::operator double() const noexcept { return type->toDouble | |||||
| String var::toString() const { return type->toString (value); } | String var::toString() const { return type->toString (value); } | ||||
| var::operator String() const { return type->toString (value); } | var::operator String() const { return type->toString (value); } | ||||
| ReferenceCountedObject* var::getObject() const noexcept { return type->toObject (value); } | ReferenceCountedObject* var::getObject() const noexcept { return type->toObject (value); } | ||||
| Array<var>* var::getArray() const noexcept { return type->toArray (value); } | |||||
| DynamicObject* var::getDynamicObject() const noexcept { return dynamic_cast <DynamicObject*> (getObject()); } | DynamicObject* var::getDynamicObject() const noexcept { return dynamic_cast <DynamicObject*> (getObject()); } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -391,6 +437,7 @@ const var& var::operator= (const double newValue) { type->cleanUp (v | |||||
| const var& var::operator= (const char* const newValue) { var v (newValue); swapWith (v); return *this; } | const var& var::operator= (const char* const newValue) { var v (newValue); swapWith (v); return *this; } | ||||
| const var& var::operator= (const wchar_t* const newValue) { var v (newValue); swapWith (v); return *this; } | const var& var::operator= (const wchar_t* const newValue) { var v (newValue); swapWith (v); return *this; } | ||||
| const var& var::operator= (const String& newValue) { var v (newValue); swapWith (v); return *this; } | const var& var::operator= (const String& newValue) { var v (newValue); swapWith (v); return *this; } | ||||
| const var& var::operator= (const Array<var>& newValue) { var v (newValue); swapWith (v); return *this; } | |||||
| const var& var::operator= (ReferenceCountedObject* newValue) { var v (newValue); swapWith (v); return *this; } | const var& var::operator= (ReferenceCountedObject* newValue) { var v (newValue); swapWith (v); return *this; } | ||||
| const var& var::operator= (MethodFunction newValue) { var v (newValue); swapWith (v); return *this; } | const var& var::operator= (MethodFunction newValue) { var v (newValue); swapWith (v); return *this; } | ||||
| @@ -414,38 +461,6 @@ bool operator!= (const var& v1, const char* const v2) { return v1.toString | |||||
| //============================================================================== | //============================================================================== | ||||
| void var::writeToStream (OutputStream& output) const | |||||
| { | |||||
| type->writeToStream (value, output); | |||||
| } | |||||
| var var::readFromStream (InputStream& input) | |||||
| { | |||||
| const int numBytes = input.readCompressedInt(); | |||||
| if (numBytes > 0) | |||||
| { | |||||
| switch (input.readByte()) | |||||
| { | |||||
| case varMarker_Int: return var (input.readInt()); | |||||
| case varMarker_Int64: return var (input.readInt64()); | |||||
| case varMarker_BoolTrue: return var (true); | |||||
| case varMarker_BoolFalse: return var (false); | |||||
| case varMarker_Double: return var (input.readDouble()); | |||||
| case varMarker_String: | |||||
| { | |||||
| MemoryOutputStream mo; | |||||
| mo.writeFromInputStream (input, numBytes - 1); | |||||
| return var (mo.toUTF8()); | |||||
| } | |||||
| default: input.skipNextBytes (numBytes - 1); break; | |||||
| } | |||||
| } | |||||
| return var::null; | |||||
| } | |||||
| var var::operator[] (const Identifier& propertyName) const | var var::operator[] (const Identifier& propertyName) const | ||||
| { | { | ||||
| DynamicObject* const o = getDynamicObject(); | DynamicObject* const o = getDynamicObject(); | ||||
| @@ -502,5 +517,126 @@ var var::call (const Identifier& method, const var& arg1, const var& arg2, const | |||||
| return invoke (method, args, 5); | return invoke (method, args, 5); | ||||
| } | } | ||||
| //============================================================================== | |||||
| int var::size() const | |||||
| { | |||||
| const Array<var>* const array = getArray(); | |||||
| return array != nullptr ? array->size() : 0; | |||||
| } | |||||
| const var& var::operator[] (int arrayIndex) const | |||||
| { | |||||
| const Array<var>* const array = getArray(); | |||||
| // When using this method, the var must actually be an array, and the index | |||||
| // must be in-range! | |||||
| jassert (array != nullptr && isPositiveAndBelow (arrayIndex, array->size())); | |||||
| return array->getReference (arrayIndex); | |||||
| } | |||||
| var& var::operator[] (int arrayIndex) | |||||
| { | |||||
| const Array<var>* const array = getArray(); | |||||
| // When using this method, the var must actually be an array, and the index | |||||
| // must be in-range! | |||||
| jassert (array != nullptr && isPositiveAndBelow (arrayIndex, array->size())); | |||||
| return array->getReference (arrayIndex); | |||||
| } | |||||
| Array<var>* var::convertToArray() | |||||
| { | |||||
| Array<var>* array = getArray(); | |||||
| if (array == nullptr) | |||||
| { | |||||
| const Array<var> tempVar; | |||||
| var v (tempVar); | |||||
| array = v.value.arrayValue; | |||||
| if (! isVoid()) | |||||
| array->add (*this); | |||||
| swapWith (v); | |||||
| } | |||||
| return array; | |||||
| } | |||||
| void var::append (const var& value) | |||||
| { | |||||
| convertToArray()->add (value); | |||||
| } | |||||
| void var::remove (const int index) | |||||
| { | |||||
| Array<var>* const array = getArray(); | |||||
| if (array != nullptr) | |||||
| array->remove (index); | |||||
| } | |||||
| void var::insert (const int index, const var& value) | |||||
| { | |||||
| convertToArray()->insert (index, value); | |||||
| } | |||||
| void var::resize (const int numArrayElementsWanted) | |||||
| { | |||||
| convertToArray()->resize (numArrayElementsWanted); | |||||
| } | |||||
| int var::indexOf (const var& value) const | |||||
| { | |||||
| const Array<var>* const array = getArray(); | |||||
| return array != nullptr ? array->indexOf (value) : -1; | |||||
| } | |||||
| //============================================================================== | |||||
| void var::writeToStream (OutputStream& output) const | |||||
| { | |||||
| type->writeToStream (value, output); | |||||
| } | |||||
| var var::readFromStream (InputStream& input) | |||||
| { | |||||
| const int numBytes = input.readCompressedInt(); | |||||
| if (numBytes > 0) | |||||
| { | |||||
| switch (input.readByte()) | |||||
| { | |||||
| case varMarker_Int: return var (input.readInt()); | |||||
| case varMarker_Int64: return var (input.readInt64()); | |||||
| case varMarker_BoolTrue: return var (true); | |||||
| case varMarker_BoolFalse: return var (false); | |||||
| case varMarker_Double: return var (input.readDouble()); | |||||
| case varMarker_String: | |||||
| { | |||||
| MemoryOutputStream mo; | |||||
| mo.writeFromInputStream (input, numBytes - 1); | |||||
| return var (mo.toUTF8()); | |||||
| } | |||||
| case varMarker_Array: | |||||
| { | |||||
| var v; | |||||
| Array<var>* const destArray = v.convertToArray(); | |||||
| for (int i = input.readCompressedInt(); --i >= 0;) | |||||
| destArray->add (readFromStream (input)); | |||||
| return v; | |||||
| } | |||||
| default: input.skipNextBytes (numBytes - 1); break; | |||||
| } | |||||
| } | |||||
| return var::null; | |||||
| } | |||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| @@ -29,6 +29,7 @@ | |||||
| #include "../text/juce_Identifier.h" | #include "../text/juce_Identifier.h" | ||||
| #include "../io/streams/juce_OutputStream.h" | #include "../io/streams/juce_OutputStream.h" | ||||
| #include "../io/streams/juce_InputStream.h" | #include "../io/streams/juce_InputStream.h" | ||||
| #include "../containers/juce_Array.h" | |||||
| #ifndef DOXYGEN | #ifndef DOXYGEN | ||||
| class ReferenceCountedObject; | class ReferenceCountedObject; | ||||
| @@ -70,6 +71,7 @@ public: | |||||
| var (const char* value); | var (const char* value); | ||||
| var (const wchar_t* value); | var (const wchar_t* value); | ||||
| var (const String& value); | var (const String& value); | ||||
| var (const Array<var>& value); | |||||
| var (ReferenceCountedObject* object); | var (ReferenceCountedObject* object); | ||||
| var (MethodFunction method) noexcept; | var (MethodFunction method) noexcept; | ||||
| @@ -81,6 +83,7 @@ public: | |||||
| const var& operator= (const char* value); | const var& operator= (const char* value); | ||||
| const var& operator= (const wchar_t* value); | const var& operator= (const wchar_t* value); | ||||
| const var& operator= (const String& value); | const var& operator= (const String& value); | ||||
| const var& operator= (const Array<var>& value); | |||||
| const var& operator= (ReferenceCountedObject* object); | const var& operator= (ReferenceCountedObject* object); | ||||
| const var& operator= (MethodFunction method); | const var& operator= (MethodFunction method); | ||||
| @@ -93,6 +96,7 @@ public: | |||||
| operator double() const noexcept; | operator double() const noexcept; | ||||
| operator String() const; | operator String() const; | ||||
| String toString() const; | String toString() const; | ||||
| Array<var>* getArray() const noexcept; | |||||
| ReferenceCountedObject* getObject() const noexcept; | ReferenceCountedObject* getObject() const noexcept; | ||||
| DynamicObject* getDynamicObject() const noexcept; | DynamicObject* getDynamicObject() const noexcept; | ||||
| @@ -103,25 +107,89 @@ public: | |||||
| bool isDouble() const noexcept; | bool isDouble() const noexcept; | ||||
| bool isString() const noexcept; | bool isString() const noexcept; | ||||
| bool isObject() const noexcept; | bool isObject() const noexcept; | ||||
| bool isArray() const noexcept; | |||||
| bool isMethod() const noexcept; | bool isMethod() const noexcept; | ||||
| /** Returns true if this var has the same value as the one supplied. | |||||
| Note that this ignores the type, so a string var "123" and an integer var with the | |||||
| value 123 are considered to be equal. | |||||
| @see equalsWithSameType | |||||
| */ | |||||
| bool equals (const var& other) const noexcept; | |||||
| /** Returns true if this var has the same value and type as the one supplied. | |||||
| This differs from equals() because e.g. "123" and 123 will be considered different. | |||||
| @see equals | |||||
| */ | |||||
| bool equalsWithSameType (const var& other) const noexcept; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Writes a binary representation of this value to a stream. | |||||
| The data can be read back later using readFromStream(). | |||||
| /** If the var is an array, this returns the number of elements. | |||||
| If the var isn't actually an array, this will return 0. | |||||
| */ | */ | ||||
| void writeToStream (OutputStream& output) const; | |||||
| int size() const; | |||||
| /** If the var is an array, this can be used to return one of its elements. | |||||
| To call this method, you must make sure that the var is actually an array, and | |||||
| that the index is a valid number. If these conditions aren't met, behaviour is | |||||
| undefined. | |||||
| For more control over the array's contents, you can call getArray() and manipulate | |||||
| it directly as an Array<var>. | |||||
| */ | |||||
| const var& operator[] (int arrayIndex) const; | |||||
| /** If the var is an array, this can be used to return one of its elements. | |||||
| To call this method, you must make sure that the var is actually an array, and | |||||
| that the index is a valid number. If these conditions aren't met, behaviour is | |||||
| undefined. | |||||
| For more control over the array's contents, you can call getArray() and manipulate | |||||
| it directly as an Array<var>. | |||||
| */ | |||||
| var& operator[] (int arrayIndex); | |||||
| /** Appends an element to the var, converting it to an array if it isn't already one. | |||||
| If the var isn't an array, it will be converted to one, and if its value was non-void, | |||||
| this value will be kept as the first element of the new array. The parameter value | |||||
| will then be appended to it. | |||||
| For more control over the array's contents, you can call getArray() and manipulate | |||||
| it directly as an Array<var>. | |||||
| */ | |||||
| void append (const var& valueToAppend); | |||||
| /** Inserts an element to the var, converting it to an array if it isn't already one. | |||||
| If the var isn't an array, it will be converted to one, and if its value was non-void, | |||||
| this value will be kept as the first element of the new array. The parameter value | |||||
| will then be inserted into it. | |||||
| For more control over the array's contents, you can call getArray() and manipulate | |||||
| it directly as an Array<var>. | |||||
| */ | |||||
| void insert (int index, const var& value); | |||||
| /** Reads back a stored binary representation of a value. | |||||
| The data in the stream must have been written using writeToStream(), or this | |||||
| will have unpredictable results. | |||||
| /** If the var is an array, this removes one of its elements. | |||||
| If the index is out-of-range or the var isn't an array, nothing will be done. | |||||
| For more control over the array's contents, you can call getArray() and manipulate | |||||
| it directly as an Array<var>. | |||||
| */ | */ | ||||
| static var readFromStream (InputStream& input); | |||||
| void remove (int index); | |||||
| /** Treating the var as an array, this resizes it to contain the specified number of elements. | |||||
| If the var isn't an array, it will be converted to one, and if its value was non-void, | |||||
| this value will be kept as the first element of the new array before resizing. | |||||
| For more control over the array's contents, you can call getArray() and manipulate | |||||
| it directly as an Array<var>. | |||||
| */ | |||||
| void resize (int numArrayElementsWanted); | |||||
| /** If the var is an array, this searches it for the first occurrence of the specified value, | |||||
| and returns its index. | |||||
| If the var isn't an array, or if the value isn't found, this returns -1. | |||||
| */ | |||||
| int indexOf (const var& value) const; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** If this variant is an object, this returns one of its properties. */ | /** If this variant is an object, this returns one of its properties. */ | ||||
| var operator[] (const Identifier& propertyName) const; | var operator[] (const Identifier& propertyName) const; | ||||
| //============================================================================== | |||||
| /** If this variant is an object, this invokes one of its methods with no arguments. */ | /** If this variant is an object, this invokes one of its methods with no arguments. */ | ||||
| var call (const Identifier& method) const; | var call (const Identifier& method) const; | ||||
| /** If this variant is an object, this invokes one of its methods with one argument. */ | /** If this variant is an object, this invokes one of its methods with one argument. */ | ||||
| @@ -138,19 +206,16 @@ public: | |||||
| var invoke (const Identifier& method, const var* arguments, int numArguments) const; | var invoke (const Identifier& method, const var* arguments, int numArguments) const; | ||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns true if this var has the same value as the one supplied. | |||||
| Note that this ignores the type, so a string var "123" and an integer var with the | |||||
| value 123 are considered to be equal. | |||||
| @see equalsWithSameType | |||||
| /** Writes a binary representation of this value to a stream. | |||||
| The data can be read back later using readFromStream(). | |||||
| */ | */ | ||||
| bool equals (const var& other) const noexcept; | |||||
| void writeToStream (OutputStream& output) const; | |||||
| /** Returns true if this var has the same value and type as the one supplied. | |||||
| This differs from equals() because e.g. "123" and 123 will be considered different. | |||||
| @see equals | |||||
| /** Reads back a stored binary representation of a value. | |||||
| The data in the stream must have been written using writeToStream(), or this | |||||
| will have unpredictable results. | |||||
| */ | */ | ||||
| bool equalsWithSameType (const var& other) const noexcept; | |||||
| static var readFromStream (InputStream& input); | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -162,6 +227,7 @@ private: | |||||
| class VariantType_Bool; friend class VariantType_Bool; | class VariantType_Bool; friend class VariantType_Bool; | ||||
| class VariantType_String; friend class VariantType_String; | class VariantType_String; friend class VariantType_String; | ||||
| class VariantType_Object; friend class VariantType_Object; | class VariantType_Object; friend class VariantType_Object; | ||||
| class VariantType_Array; friend class VariantType_Array; | |||||
| class VariantType_Method; friend class VariantType_Method; | class VariantType_Method; friend class VariantType_Method; | ||||
| union ValueUnion | union ValueUnion | ||||
| @@ -172,12 +238,14 @@ private: | |||||
| double doubleValue; | double doubleValue; | ||||
| char stringValue [sizeof (String)]; | char stringValue [sizeof (String)]; | ||||
| ReferenceCountedObject* objectValue; | ReferenceCountedObject* objectValue; | ||||
| Array<var>* arrayValue; | |||||
| MethodFunction methodValue; | MethodFunction methodValue; | ||||
| }; | }; | ||||
| const VariantType* type; | const VariantType* type; | ||||
| ValueUnion value; | ValueUnion value; | ||||
| Array<var>* convertToArray(); | |||||
| friend class DynamicObject; | friend class DynamicObject; | ||||
| var invokeMethod (DynamicObject*, const var*, int) const; | var invokeMethod (DynamicObject*, const var*, int) const; | ||||
| }; | }; | ||||
| @@ -33,7 +33,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 53 | #define JUCE_MINOR_VERSION 53 | ||||
| #define JUCE_BUILDNUMBER 97 | |||||
| #define JUCE_BUILDNUMBER 98 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -121,4 +121,19 @@ bool FileOutputStream::write (const void* const src, const int numBytes) | |||||
| return true; | return true; | ||||
| } | } | ||||
| void FileOutputStream::writeRepeatedByte (uint8 byte, int numBytes) | |||||
| { | |||||
| if (bytesInBuffer + numBytes < bufferSize) | |||||
| { | |||||
| memset (buffer + bytesInBuffer, byte, numBytes); | |||||
| bytesInBuffer += numBytes; | |||||
| currentPosition += numBytes; | |||||
| } | |||||
| else | |||||
| { | |||||
| OutputStream::writeRepeatedByte (byte, numBytes); | |||||
| } | |||||
| } | |||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| @@ -83,6 +83,7 @@ public: | |||||
| int64 getPosition(); | int64 getPosition(); | ||||
| bool setPosition (int64 pos); | bool setPosition (int64 pos); | ||||
| bool write (const void* data, int numBytes); | bool write (const void* data, int numBytes); | ||||
| void writeRepeatedByte (uint8 byte, int numTimesToRepeat); | |||||
| private: | private: | ||||
| @@ -77,15 +77,19 @@ void MemoryOutputStream::reset() noexcept | |||||
| size = 0; | size = 0; | ||||
| } | } | ||||
| void MemoryOutputStream::prepareToWrite (int numBytes) | |||||
| { | |||||
| const size_t storageNeeded = position + numBytes; | |||||
| if (storageNeeded >= data.getSize()) | |||||
| data.ensureSize ((storageNeeded + jmin ((int) (storageNeeded / 2), 1024 * 1024) + 32) & ~31); | |||||
| } | |||||
| bool MemoryOutputStream::write (const void* const buffer, int howMany) | bool MemoryOutputStream::write (const void* const buffer, int howMany) | ||||
| { | { | ||||
| if (howMany > 0) | if (howMany > 0) | ||||
| { | { | ||||
| const size_t storageNeeded = position + howMany; | |||||
| if (storageNeeded >= data.getSize()) | |||||
| data.ensureSize ((storageNeeded + jmin ((int) (storageNeeded / 2), 1024 * 1024) + 32) & ~31); | |||||
| prepareToWrite (howMany); | |||||
| memcpy (static_cast<char*> (data.getData()) + position, buffer, howMany); | memcpy (static_cast<char*> (data.getData()) + position, buffer, howMany); | ||||
| position += howMany; | position += howMany; | ||||
| size = jmax (size, position); | size = jmax (size, position); | ||||
| @@ -94,6 +98,17 @@ bool MemoryOutputStream::write (const void* const buffer, int howMany) | |||||
| return true; | return true; | ||||
| } | } | ||||
| void MemoryOutputStream::writeRepeatedByte (uint8 byte, int howMany) | |||||
| { | |||||
| if (howMany > 0) | |||||
| { | |||||
| prepareToWrite (howMany); | |||||
| memset (static_cast<char*> (data.getData()) + position, byte, howMany); | |||||
| position += howMany; | |||||
| size = jmax (size, position); | |||||
| } | |||||
| } | |||||
| const void* MemoryOutputStream::getData() const noexcept | const void* MemoryOutputStream::getData() const noexcept | ||||
| { | { | ||||
| void* const d = data.getData(); | void* const d = data.getData(); | ||||
| @@ -108,7 +108,7 @@ public: | |||||
| int64 getPosition() { return position; } | int64 getPosition() { return position; } | ||||
| bool setPosition (int64 newPosition); | bool setPosition (int64 newPosition); | ||||
| int writeFromInputStream (InputStream& source, int64 maxNumBytesToWrite); | int writeFromInputStream (InputStream& source, int64 maxNumBytesToWrite); | ||||
| void writeRepeatedByte (uint8 byte, int numTimesToRepeat); | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -117,6 +117,7 @@ private: | |||||
| size_t position, size; | size_t position, size; | ||||
| void trimExternalBlockSize(); | void trimExternalBlockSize(); | ||||
| void prepareToWrite (int numBytes); | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryOutputStream); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryOutputStream); | ||||
| }; | }; | ||||
| @@ -260,6 +260,9 @@ | |||||
| #ifndef __JUCE_IDENTIFIER_JUCEHEADER__ | #ifndef __JUCE_IDENTIFIER_JUCEHEADER__ | ||||
| #include "text/juce_Identifier.h" | #include "text/juce_Identifier.h" | ||||
| #endif | #endif | ||||
| #ifndef __JUCE_JSON_JUCEHEADER__ | |||||
| #include "text/juce_JSON.h" | |||||
| #endif | |||||
| #ifndef __JUCE_LOCALISEDSTRINGS_JUCEHEADER__ | #ifndef __JUCE_LOCALISEDSTRINGS_JUCEHEADER__ | ||||
| #include "text/juce_LocalisedStrings.h" | #include "text/juce_LocalisedStrings.h" | ||||
| #endif | #endif | ||||
| @@ -0,0 +1,532 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2004-11 by Raw Material Software Ltd. | |||||
| ------------------------------------------------------------------------------ | |||||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||||
| Public License (Version 2), as published by the Free Software Foundation. | |||||
| A copy of the license is included in the JUCE distribution, or can be found | |||||
| online at www.gnu.org/licenses. | |||||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
| ------------------------------------------------------------------------------ | |||||
| To release a closed-source product which uses JUCE, commercial licenses are | |||||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||||
| ============================================================================== | |||||
| */ | |||||
| #include "../core/juce_StandardHeader.h" | |||||
| BEGIN_JUCE_NAMESPACE | |||||
| #include "juce_JSON.h" | |||||
| #include "../io/files/juce_File.h" | |||||
| #include "../io/streams/juce_MemoryOutputStream.h" | |||||
| #include "../containers/juce_DynamicObject.h" | |||||
| //============================================================================== | |||||
| class JSONParser | |||||
| { | |||||
| public: | |||||
| static Result parseAny (String::CharPointerType& t, var& result) | |||||
| { | |||||
| t = t.findEndOfWhitespace(); | |||||
| String::CharPointerType t2 (t); | |||||
| switch (t2.getAndAdvance()) | |||||
| { | |||||
| case '{': t = t2; return parseObject (t, result); | |||||
| case '[': t = t2; return parseArray (t, result); | |||||
| case '"': t = t2; return parseString (t, result); | |||||
| case '-': | |||||
| t2 = t2.findEndOfWhitespace(); | |||||
| if (! CharacterFunctions::isDigit (*t2)) | |||||
| break; | |||||
| t = t2; | |||||
| return parseNumber (t, result, true); | |||||
| case '0': case '1': case '2': case '3': case '4': | |||||
| case '5': case '6': case '7': case '8': case '9': | |||||
| return parseNumber (t, result, false); | |||||
| case 't': // "true" | |||||
| if (t2.getAndAdvance() == 'r' && t2.getAndAdvance() == 'u' && t2.getAndAdvance() == 'e') | |||||
| { | |||||
| t = t2; | |||||
| result = var (true); | |||||
| return Result::ok(); | |||||
| } | |||||
| break; | |||||
| case 'f': // "false" | |||||
| if (t2.getAndAdvance() == 'a' && t2.getAndAdvance() == 'l' | |||||
| && t2.getAndAdvance() == 's' && t2.getAndAdvance() == 'e') | |||||
| { | |||||
| t = t2; | |||||
| result = var (false); | |||||
| return Result::ok(); | |||||
| } | |||||
| break; | |||||
| case 'n': // "null" | |||||
| if (t2.getAndAdvance() == 'u' && t2.getAndAdvance() == 'l' && t2.getAndAdvance() == 'l') | |||||
| { | |||||
| t = t2; | |||||
| result = var::null; | |||||
| return Result::ok(); | |||||
| } | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| return createFail ("Syntax error", &t); | |||||
| } | |||||
| private: | |||||
| static Result createFail (const char* const message, const String::CharPointerType* location = nullptr) | |||||
| { | |||||
| String m (message); | |||||
| if (location != nullptr) | |||||
| m << ": \"" << String (*location, 20) << '"'; | |||||
| return Result::fail (m); | |||||
| } | |||||
| static Result parseNumber (String::CharPointerType& t, var& result, const bool isNegative) | |||||
| { | |||||
| String::CharPointerType oldT (t); | |||||
| int64 intValue = t.getAndAdvance() - '0'; | |||||
| jassert (intValue >= 0 && intValue < 10); | |||||
| for (;;) | |||||
| { | |||||
| String::CharPointerType previousChar (t); | |||||
| const juce_wchar c = t.getAndAdvance(); | |||||
| const int digit = ((int) c) - '0'; | |||||
| if (isPositiveAndBelow (digit, 10)) | |||||
| { | |||||
| intValue = intValue * 10 + digit; | |||||
| continue; | |||||
| } | |||||
| if (c == 'e' || c == 'E' || c == '.') | |||||
| { | |||||
| t = oldT; | |||||
| const double asDouble = CharacterFunctions::readDoubleValue (t); | |||||
| result = isNegative ? -asDouble : asDouble; | |||||
| return Result::ok(); | |||||
| } | |||||
| if (CharacterFunctions::isWhitespace (c) | |||||
| || c == ',' || c == '}' || c == ']' || c == 0) | |||||
| { | |||||
| t = previousChar; | |||||
| break; | |||||
| } | |||||
| return createFail ("Syntax error in number", &oldT); | |||||
| } | |||||
| const int64 correctedValue = isNegative ? -intValue : intValue; | |||||
| if ((intValue >> 31) != 0) | |||||
| result = correctedValue; | |||||
| else | |||||
| result = (int) correctedValue; | |||||
| return Result::ok(); | |||||
| } | |||||
| static Result parseObject (String::CharPointerType& t, var& result) | |||||
| { | |||||
| DynamicObject* const resultObject = new DynamicObject(); | |||||
| result = resultObject; | |||||
| for (;;) | |||||
| { | |||||
| t = t.findEndOfWhitespace(); | |||||
| String::CharPointerType oldT (t); | |||||
| const juce_wchar c = t.getAndAdvance(); | |||||
| if (c == '}') | |||||
| break; | |||||
| if (c == 0) | |||||
| return createFail ("Unexpected end-of-input in object declaration"); | |||||
| if (c == '"') | |||||
| { | |||||
| var propertyNameVar; | |||||
| Result r (parseString (t, propertyNameVar)); | |||||
| if (r.failed()) | |||||
| return r; | |||||
| const String propertyName (propertyNameVar.toString()); | |||||
| if (propertyName.isNotEmpty()) | |||||
| { | |||||
| t = t.findEndOfWhitespace(); | |||||
| oldT = t; | |||||
| const juce_wchar c = t.getAndAdvance(); | |||||
| if (c != ':') | |||||
| return createFail ("Expected ':', but found", &oldT); | |||||
| var propertyValue; | |||||
| Result r (parseAny (t, propertyValue)); | |||||
| if (r.failed()) | |||||
| return r; | |||||
| resultObject->setProperty (propertyName, propertyValue); | |||||
| t = t.findEndOfWhitespace(); | |||||
| oldT = t; | |||||
| const juce_wchar nextChar = t.getAndAdvance(); | |||||
| if (nextChar == ',') | |||||
| continue; | |||||
| else if (nextChar == '}') | |||||
| break; | |||||
| } | |||||
| } | |||||
| return createFail ("Expected object member declaration, but found", &oldT); | |||||
| } | |||||
| return Result::ok(); | |||||
| } | |||||
| static Result parseArray (String::CharPointerType& t, var& result) | |||||
| { | |||||
| result = var (Array<var>()); | |||||
| Array<var>* const destArray = result.getArray(); | |||||
| for (;;) | |||||
| { | |||||
| t = t.findEndOfWhitespace(); | |||||
| String::CharPointerType oldT (t); | |||||
| const juce_wchar c = t.getAndAdvance(); | |||||
| if (c == ']') | |||||
| break; | |||||
| if (c == 0) | |||||
| return createFail ("Unexpected end-of-input in array declaration"); | |||||
| t = oldT; | |||||
| destArray->add (var::null); | |||||
| Result r (parseAny (t, destArray->getReference (destArray->size() - 1))); | |||||
| if (r.failed()) | |||||
| return r; | |||||
| t = t.findEndOfWhitespace(); | |||||
| oldT = t; | |||||
| const juce_wchar nextChar = t.getAndAdvance(); | |||||
| if (nextChar == ',') | |||||
| continue; | |||||
| else if (nextChar == ']') | |||||
| break; | |||||
| return createFail ("Expected object array item, but found", &oldT); | |||||
| } | |||||
| return Result::ok(); | |||||
| } | |||||
| static Result parseString (String::CharPointerType& t, var& result) | |||||
| { | |||||
| Array<juce_wchar> buffer; | |||||
| buffer.ensureStorageAllocated (256); | |||||
| for (;;) | |||||
| { | |||||
| juce_wchar c = t.getAndAdvance(); | |||||
| if (c == '"') | |||||
| break; | |||||
| if (c == '\\') | |||||
| { | |||||
| c = t.getAndAdvance(); | |||||
| switch (c) | |||||
| { | |||||
| case '"': | |||||
| case '\\': | |||||
| case '/': break; | |||||
| case 'b': c = '\b'; break; | |||||
| case 'f': c = '\f'; break; | |||||
| case 'n': c = '\n'; break; | |||||
| case 'r': c = '\r'; break; | |||||
| case 't': c = '\t'; break; | |||||
| case 'u': | |||||
| { | |||||
| c = 0; | |||||
| for (int i = 4; --i >= 0;) | |||||
| { | |||||
| const int digitValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance()); | |||||
| if (digitValue < 0) | |||||
| return createFail ("Syntax error in unicode escape sequence"); | |||||
| c = (juce_wchar) ((c << 4) + digitValue); | |||||
| } | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| if (c == 0) | |||||
| return createFail ("Unexpected end-of-input in string constant"); | |||||
| buffer.add (c); | |||||
| } | |||||
| buffer.add (0); | |||||
| result = String (CharPointer_UTF32 (buffer.getRawDataPointer())); | |||||
| return Result::ok(); | |||||
| } | |||||
| }; | |||||
| //============================================================================== | |||||
| class JSONFormatter | |||||
| { | |||||
| public: | |||||
| static void write (OutputStream& out, const var& v, | |||||
| const int indentLevel, const bool allOnOneLine) | |||||
| { | |||||
| if (v.isString()) | |||||
| { | |||||
| writeString (out, v.toString().getCharPointer()); | |||||
| } | |||||
| else if (v.isVoid()) | |||||
| { | |||||
| out << "null"; | |||||
| } | |||||
| else if (v.isBool()) | |||||
| { | |||||
| out << (static_cast<bool> (v) ? "true" : "false"); | |||||
| } | |||||
| else if (v.isArray()) | |||||
| { | |||||
| writeArray (out, *v.getArray(), indentLevel, allOnOneLine); | |||||
| } | |||||
| else if (v.isObject()) | |||||
| { | |||||
| DynamicObject* object = dynamic_cast<DynamicObject*> (v.getObject()); | |||||
| jassert (object != nullptr); // Only DynamicObjects can be converted to JSON! | |||||
| writeObject (out, *object, indentLevel, allOnOneLine); | |||||
| } | |||||
| else | |||||
| { | |||||
| jassert (! v.isMethod()); // Can't convert an object with methods to JSON! | |||||
| out << v.toString(); | |||||
| } | |||||
| } | |||||
| private: | |||||
| enum { indentSize = 2 }; | |||||
| static void writeEscapedChar (OutputStream& out, const unsigned short value) | |||||
| { | |||||
| out << "\\u" << String::toHexString ((int) value).paddedLeft ('0', 4); | |||||
| } | |||||
| static void writeString (OutputStream& out, String::CharPointerType t) | |||||
| { | |||||
| out << '"'; | |||||
| for (;;) | |||||
| { | |||||
| const juce_wchar c (t.getAndAdvance()); | |||||
| switch (c) | |||||
| { | |||||
| case 0: out << '"'; return; | |||||
| case '\"': out << "\\\""; break; | |||||
| case '\\': out << "\\\\"; break; | |||||
| case '\b': out << "\\b"; break; | |||||
| case '\f': out << "\\f"; break; | |||||
| case '\t': out << "\\t"; break; | |||||
| case '\r': out << "\\r"; break; | |||||
| case '\n': out << "\\n"; break; | |||||
| default: | |||||
| if (c >= 32 && c < 127) | |||||
| { | |||||
| out << (char) c; | |||||
| } | |||||
| else | |||||
| { | |||||
| if (CharPointer_UTF16::getBytesRequiredFor (c) > 2) | |||||
| { | |||||
| CharPointer_UTF16::CharType chars[2]; | |||||
| CharPointer_UTF16 utf16 (chars); | |||||
| utf16.write (c); | |||||
| for (int i = 0; i < 2; ++i) | |||||
| writeEscapedChar (out, (unsigned short) chars[i]); | |||||
| } | |||||
| else | |||||
| { | |||||
| writeEscapedChar (out, (unsigned short) c); | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| static void writeSpaces (OutputStream& out, int numSpaces) | |||||
| { | |||||
| out.writeRepeatedByte (' ', numSpaces); | |||||
| } | |||||
| static void writeArray (OutputStream& out, const Array<var>& array, | |||||
| const int indentLevel, const bool allOnOneLine) | |||||
| { | |||||
| out << '['; | |||||
| if (! allOnOneLine) | |||||
| out << newLine; | |||||
| for (int i = 0; i < array.size(); ++i) | |||||
| { | |||||
| if (! allOnOneLine) | |||||
| writeSpaces (out, indentLevel + indentSize); | |||||
| write (out, array.getReference(i), indentLevel + indentSize, allOnOneLine); | |||||
| if (i < array.size() - 1) | |||||
| { | |||||
| if (allOnOneLine) | |||||
| out << ", "; | |||||
| else | |||||
| out << ',' << newLine; | |||||
| } | |||||
| else if (! allOnOneLine) | |||||
| out << newLine; | |||||
| } | |||||
| if (! allOnOneLine) | |||||
| writeSpaces (out, indentLevel); | |||||
| out << ']'; | |||||
| } | |||||
| static void writeObject (OutputStream& out, DynamicObject& object, | |||||
| const int indentLevel, const bool allOnOneLine) | |||||
| { | |||||
| NamedValueSet& props = object.getProperties(); | |||||
| out << '{'; | |||||
| if (! allOnOneLine) | |||||
| out << newLine; | |||||
| LinkedListPointer<NamedValueSet::NamedValue>* i = &(props.values); | |||||
| for (;;) | |||||
| { | |||||
| NamedValueSet::NamedValue* const v = i->get(); | |||||
| if (v == nullptr) | |||||
| break; | |||||
| if (! allOnOneLine) | |||||
| writeSpaces (out, indentLevel + indentSize); | |||||
| writeString (out, v->name); | |||||
| out << ": "; | |||||
| write (out, v->value, indentLevel + indentSize, allOnOneLine); | |||||
| if (v->nextListItem.get() != nullptr) | |||||
| { | |||||
| if (allOnOneLine) | |||||
| out << ", "; | |||||
| else | |||||
| out << ',' << newLine; | |||||
| } | |||||
| else if (! allOnOneLine) | |||||
| out << newLine; | |||||
| i = &(v->nextListItem); | |||||
| } | |||||
| if (! allOnOneLine) | |||||
| writeSpaces (out, indentLevel); | |||||
| out << '}'; | |||||
| } | |||||
| }; | |||||
| //============================================================================== | |||||
| var JSON::parse (const String& text) | |||||
| { | |||||
| var result; | |||||
| String::CharPointerType t (text.getCharPointer()); | |||||
| if (! JSONParser::parseAny (t, result)) | |||||
| result = var::null; | |||||
| return result; | |||||
| } | |||||
| var JSON::parse (InputStream& input) | |||||
| { | |||||
| return parse (input.readEntireStreamAsString()); | |||||
| } | |||||
| var JSON::parse (const File& file) | |||||
| { | |||||
| return parse (file.loadFileAsString()); | |||||
| } | |||||
| Result JSON::parse (const String& text, var& result) | |||||
| { | |||||
| String::CharPointerType t (text.getCharPointer()); | |||||
| return JSONParser::parseAny (t, result); | |||||
| } | |||||
| String JSON::toString (const var& data, const bool allOnOneLine) | |||||
| { | |||||
| MemoryOutputStream mo (1024); | |||||
| JSONFormatter::write (mo, data, 0, allOnOneLine); | |||||
| return mo.toString(); | |||||
| } | |||||
| void JSON::writeToStream (OutputStream& output, const var& data, const bool allOnOneLine) | |||||
| { | |||||
| JSONFormatter::write (output, data, 0, allOnOneLine); | |||||
| } | |||||
| END_JUCE_NAMESPACE | |||||
| @@ -0,0 +1,115 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2004-11 by Raw Material Software Ltd. | |||||
| ------------------------------------------------------------------------------ | |||||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||||
| Public License (Version 2), as published by the Free Software Foundation. | |||||
| A copy of the license is included in the JUCE distribution, or can be found | |||||
| online at www.gnu.org/licenses. | |||||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
| ------------------------------------------------------------------------------ | |||||
| To release a closed-source product which uses JUCE, commercial licenses are | |||||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||||
| ============================================================================== | |||||
| */ | |||||
| #ifndef __JUCE_JSON_JUCEHEADER__ | |||||
| #define __JUCE_JSON_JUCEHEADER__ | |||||
| #include "../core/juce_Result.h" | |||||
| #include "../containers/juce_Variant.h" | |||||
| class InputStream; | |||||
| class OutputStream; | |||||
| class File; | |||||
| //============================================================================== | |||||
| /** | |||||
| Contains static methods for converting JSON-formatted text to and from var objects. | |||||
| The var class is structurally compatible with JSON-formatted data, so these | |||||
| functions allow you to parse JSON into a var object, and to convert a var | |||||
| object to JSON-formatted text. | |||||
| @see var | |||||
| */ | |||||
| class JSON | |||||
| { | |||||
| public: | |||||
| //============================================================================== | |||||
| /** Parses a string of JSON-formatted text, and returns a result code containing | |||||
| any parse errors. | |||||
| This will return the parsed structure in the parsedResult parameter, and will | |||||
| return a Result object to indicate whether parsing was successful, and if not, | |||||
| it will contain an error message. | |||||
| If you're not interested in the error message, you can use one of the other | |||||
| shortcut parse methods, which simply return a var::null if the parsing fails. | |||||
| */ | |||||
| static Result parse (const String& text, var& parsedResult); | |||||
| /** Attempts to parse some JSON-formatted text, and returns the result as a var object. | |||||
| If the parsing fails, this simply returns var::null - if you need to find out more | |||||
| detail about the parse error, use the alternative parse() method which returns a Result. | |||||
| */ | |||||
| static var parse (const String& text); | |||||
| /** Attempts to parse some JSON-formatted text from a file, and returns the result | |||||
| as a var object. | |||||
| Note that this is just a short-cut for reading the entire file into a string and | |||||
| parsing the result. | |||||
| If the parsing fails, this simply returns var::null - if you need to find out more | |||||
| detail about the parse error, use the alternative parse() method which returns a Result. | |||||
| */ | |||||
| static var parse (const File& file); | |||||
| /** Attempts to parse some JSON-formatted text from a stream, and returns the result | |||||
| as a var object. | |||||
| Note that this is just a short-cut for reading the entire stream into a string and | |||||
| parsing the result. | |||||
| If the parsing fails, this simply returns var::null - if you need to find out more | |||||
| detail about the parse error, use the alternative parse() method which returns a Result. | |||||
| */ | |||||
| static var parse (InputStream& input); | |||||
| //============================================================================== | |||||
| /** Returns a string which contains a JSON-formatted representation of the var object. | |||||
| If allOnOneLine is true, the result will be compacted into a single line of text | |||||
| with no carriage-returns. If false, it will be laid-out in a more human-readable format. | |||||
| @see writeToStream | |||||
| */ | |||||
| static String toString (const var& objectToFormat, | |||||
| bool allOnOneLine = false); | |||||
| /** Writes a JSON-formatted representation of the var object to the given stream. | |||||
| If allOnOneLine is true, the result will be compacted into a single line of text | |||||
| with no carriage-returns. If false, it will be laid-out in a more human-readable format. | |||||
| @see toString | |||||
| */ | |||||
| static void writeToStream (OutputStream& output, | |||||
| const var& objectToFormat, | |||||
| bool allOnOneLine = false); | |||||
| private: | |||||
| //============================================================================== | |||||
| JSON(); // This class can't be instantiated - just use its static methods. | |||||
| }; | |||||
| #endif // __JUCE_JSON_JUCEHEADER__ | |||||
| @@ -193,21 +193,9 @@ namespace XmlOutputFunctions | |||||
| } | } | ||||
| } | } | ||||
| void writeSpaces (OutputStream& out, int numSpaces) | |||||
| void writeSpaces (OutputStream& out, const int numSpaces) | |||||
| { | { | ||||
| if (numSpaces > 0) | |||||
| { | |||||
| const char blanks[] = " "; | |||||
| const int blankSize = (int) numElementsInArray (blanks) - 1; | |||||
| while (numSpaces > blankSize) | |||||
| { | |||||
| out.write (blanks, blankSize); | |||||
| numSpaces -= blankSize; | |||||
| } | |||||
| out.write (blanks, numSpaces); | |||||
| } | |||||
| out.writeRepeatedByte (' ', numSpaces); | |||||
| } | } | ||||
| } | } | ||||