mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Simplify Beast:
* Remove asio HTTP classes * Remove beast::File, beast::String, beast::Stream, beast::Array, beast::MemoryBlock, beast::CriticalSection and other unused classes. * Remove unused platform-specific code. * Reduce Beast custom assert and debugging helper macros.
This commit is contained in:
@@ -236,8 +236,6 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\BeastConfig.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\Arithmetic.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\Asio.unity.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
@@ -312,8 +310,6 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\config\ConfigCheck.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\config\ContractChecks.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\config\PlatformConfig.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\config\SelectCompilerConfig.h">
|
||||
@@ -551,64 +547,8 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\Memory.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\asio.unity.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\AsyncObject.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPField.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPField.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPHeaders.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPHeaders.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPMessage.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPMessage.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPParser.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPParser.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPParserImpl.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPRequest.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPRequest.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPRequestParser.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPRequestParser.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPResponse.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPResponse.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPResponseParser.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPResponseParser.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPVersion.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPVersion.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\containers\Array.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\containers\ArrayAllocationBase.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\containers\ElementComparator.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\core.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\core.unity.cpp">
|
||||
@@ -631,88 +571,23 @@
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\diagnostic\UnitTestUtilities.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\files\DirectoryIterator.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\files\DirectoryIterator.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\files\File.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\files\File.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\files\FileInputStream.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\files\FileInputStream.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\files\FileOutputStream.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\files\FileOutputStream.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\logging\Logger.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\memory\MemoryBlock.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\memory\MemoryBlock.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\misc\Result.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\misc\Result.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\native\BasicNativeHeaders.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\native\bsd_Files.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\native\bsd_SystemStats.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\native\linux_Files.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\native\linux_SystemStats.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<None Include="..\..\src\beast\beast\module\core\native\mac_Files.mm">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\beast\module\core\native\mac_Strings.mm">
|
||||
</None>
|
||||
<None Include="..\..\src\beast\beast\module\core\native\mac_SystemStats.mm">
|
||||
</None>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\native\osx_ObjCHelpers.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\native\posix_SharedCode.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\native\win32_Files.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\native\win32_SystemStats.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\native\win32_Threads.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\streams\InputSource.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\streams\InputStream.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\streams\InputStream.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\streams\MemoryOutputStream.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\streams\MemoryOutputStream.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\streams\OutputStream.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\streams\OutputStream.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\system\StandardIncludes.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\system\SystemStats.cpp">
|
||||
@@ -725,18 +600,6 @@
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\text\LexicalCast.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\text\StringArray.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\text\StringArray.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\text\StringPairArray.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\text\StringPairArray.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\threads\CriticalSection.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\threads\ScopedLock.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\thread\DeadlineTimer.cpp">
|
||||
@@ -744,8 +607,6 @@
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\thread\DeadlineTimer.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\thread\MutexTraits.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\thread\Workers.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
@@ -758,11 +619,6 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\net\detail\Parse.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\net\DynamicBuffer.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\net\impl\DynamicBuffer.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\net\impl\IPAddressV4.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
@@ -880,35 +736,6 @@
|
||||
<ClCompile Include="..\..\src\beast\beast\streams\tests\basic_abstract_ostream.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\Strings.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\CharacterFunctions.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\CharPointer_ASCII.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\CharPointer_UTF16.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\CharPointer_UTF32.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\CharPointer_UTF8.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\strings\impl\CharacterFunctions.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\strings\impl\String.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\NewLine.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\String.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\StringCharPointerType.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\StringFromNumber.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\strings\Strings.unity.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\Threads.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\threads\impl\Stoppable.cpp">
|
||||
@@ -923,16 +750,8 @@
|
||||
<ClCompile Include="..\..\src\beast\beast\threads\impl\WaitableEvent.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\ScopedWrapperContext.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\semaphore.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\SharedLockGuard.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\SharedMutexAdapter.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\SpinLock.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\Stoppable.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\Thread.h">
|
||||
@@ -940,10 +759,6 @@
|
||||
<ClCompile Include="..\..\src\beast\beast\threads\Threads.unity.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\TryLockGuard.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\UnlockGuard.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\WaitableEvent.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\unity\hash_unity.cpp">
|
||||
@@ -1004,9 +819,6 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\utility\tagged_integer.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\utility\tests\bassert.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\utility\tests\empty_base_optimization.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
||||
@@ -91,30 +91,15 @@
|
||||
<Filter Include="beast\module\core">
|
||||
<UniqueIdentifier>{7451A33F-2734-1B7A-974D-34C35487A770}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\core\containers">
|
||||
<UniqueIdentifier>{BAA683DB-0B66-AF01-6912-22DA6987F3F8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\core\diagnostic">
|
||||
<UniqueIdentifier>{C3A6FF24-47F8-3E74-6596-7B3DFAC89E00}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\core\files">
|
||||
<UniqueIdentifier>{84C9C2E7-DDA0-3202-D3B3-CF70980F4D23}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\core\logging">
|
||||
<UniqueIdentifier>{E2E1AA2E-7817-DCA7-66A3-DBC4BAB06D5C}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\core\memory">
|
||||
<UniqueIdentifier>{EE59B06D-092E-4C80-21B1-3781040C8FF3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\core\misc">
|
||||
<UniqueIdentifier>{E09B8EC5-E735-34D5-4819-F3FCC1B2F6E0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\core\native">
|
||||
<UniqueIdentifier>{470567BD-4DEE-916D-FDEA-88C07C8975A7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\core\streams">
|
||||
<UniqueIdentifier>{67CF6E52-6894-6DA7-FCEE-781BD9D5646F}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\module\core\system">
|
||||
<UniqueIdentifier>{7CF8F964-7A09-16D5-11BB-6EF3AF2EFF09}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@@ -160,12 +145,6 @@
|
||||
<Filter Include="beast\streams\tests">
|
||||
<UniqueIdentifier>{70E19DD6-FF10-6564-8AC0-8EBA14B40DDF}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\strings">
|
||||
<UniqueIdentifier>{34E7D758-4E38-20B2-E0DA-9EB62658260C}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\strings\impl">
|
||||
<UniqueIdentifier>{E4069107-F7B4-3F9C-C5DE-EF7F7611420E}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast\threads">
|
||||
<UniqueIdentifier>{08F944AB-789E-3C7A-6322-D7567E6B5060}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@@ -657,9 +636,6 @@
|
||||
<ClInclude Include="..\..\src\BeastConfig.h">
|
||||
<Filter>.</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\Arithmetic.h">
|
||||
<Filter>beast</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\asio\Asio.unity.cpp">
|
||||
<Filter>beast\asio</Filter>
|
||||
</ClCompile>
|
||||
@@ -753,9 +729,6 @@
|
||||
<ClInclude Include="..\..\src\beast\beast\config\ConfigCheck.h">
|
||||
<Filter>beast\config</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\config\ContractChecks.h">
|
||||
<Filter>beast\config</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\config\PlatformConfig.h">
|
||||
<Filter>beast\config</Filter>
|
||||
</ClInclude>
|
||||
@@ -1068,78 +1041,9 @@
|
||||
<ClInclude Include="..\..\src\beast\beast\Memory.h">
|
||||
<Filter>beast</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\asio.unity.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\AsyncObject.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPField.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPField.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPHeaders.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPHeaders.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPMessage.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPMessage.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPParser.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPParser.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPParserImpl.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPRequest.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPRequest.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPRequestParser.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPRequestParser.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPResponse.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPResponse.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPResponseParser.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPResponseParser.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\asio\HTTPVersion.cpp">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\asio\HTTPVersion.h">
|
||||
<Filter>beast\module\asio</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\containers\Array.h">
|
||||
<Filter>beast\module\core\containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\containers\ArrayAllocationBase.h">
|
||||
<Filter>beast\module\core\containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\containers\ElementComparator.h">
|
||||
<Filter>beast\module\core\containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\core.h">
|
||||
<Filter>beast\module\core</Filter>
|
||||
</ClInclude>
|
||||
@@ -1167,105 +1071,27 @@
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\diagnostic\UnitTestUtilities.h">
|
||||
<Filter>beast\module\core\diagnostic</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\files\DirectoryIterator.cpp">
|
||||
<Filter>beast\module\core\files</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\files\DirectoryIterator.h">
|
||||
<Filter>beast\module\core\files</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\files\File.cpp">
|
||||
<Filter>beast\module\core\files</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\files\File.h">
|
||||
<Filter>beast\module\core\files</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\files\FileInputStream.cpp">
|
||||
<Filter>beast\module\core\files</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\files\FileInputStream.h">
|
||||
<Filter>beast\module\core\files</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\files\FileOutputStream.cpp">
|
||||
<Filter>beast\module\core\files</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\files\FileOutputStream.h">
|
||||
<Filter>beast\module\core\files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\logging\Logger.h">
|
||||
<Filter>beast\module\core\logging</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\memory\MemoryBlock.cpp">
|
||||
<Filter>beast\module\core\memory</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\memory\MemoryBlock.h">
|
||||
<Filter>beast\module\core\memory</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\misc\Result.cpp">
|
||||
<Filter>beast\module\core\misc</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\misc\Result.h">
|
||||
<Filter>beast\module\core\misc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\native\BasicNativeHeaders.h">
|
||||
<Filter>beast\module\core\native</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\native\bsd_Files.cpp">
|
||||
<Filter>beast\module\core\native</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\native\bsd_SystemStats.cpp">
|
||||
<Filter>beast\module\core\native</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\native\linux_Files.cpp">
|
||||
<Filter>beast\module\core\native</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\native\linux_SystemStats.cpp">
|
||||
<Filter>beast\module\core\native</Filter>
|
||||
</ClCompile>
|
||||
<None Include="..\..\src\beast\beast\module\core\native\mac_Files.mm">
|
||||
<Filter>beast\module\core\native</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\beast\module\core\native\mac_Strings.mm">
|
||||
<Filter>beast\module\core\native</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\beast\beast\module\core\native\mac_SystemStats.mm">
|
||||
<Filter>beast\module\core\native</Filter>
|
||||
</None>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\native\osx_ObjCHelpers.h">
|
||||
<Filter>beast\module\core\native</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\native\posix_SharedCode.h">
|
||||
<Filter>beast\module\core\native</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\native\win32_Files.cpp">
|
||||
<Filter>beast\module\core\native</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\native\win32_SystemStats.cpp">
|
||||
<Filter>beast\module\core\native</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\native\win32_Threads.cpp">
|
||||
<Filter>beast\module\core\native</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\streams\InputSource.h">
|
||||
<Filter>beast\module\core\streams</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\streams\InputStream.cpp">
|
||||
<Filter>beast\module\core\streams</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\streams\InputStream.h">
|
||||
<Filter>beast\module\core\streams</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\streams\MemoryOutputStream.cpp">
|
||||
<Filter>beast\module\core\streams</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\streams\MemoryOutputStream.h">
|
||||
<Filter>beast\module\core\streams</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\streams\OutputStream.cpp">
|
||||
<Filter>beast\module\core\streams</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\streams\OutputStream.h">
|
||||
<Filter>beast\module\core\streams</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\system\StandardIncludes.h">
|
||||
<Filter>beast\module\core\system</Filter>
|
||||
</ClInclude>
|
||||
@@ -1281,21 +1107,6 @@
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\text\LexicalCast.h">
|
||||
<Filter>beast\module\core\text</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\text\StringArray.cpp">
|
||||
<Filter>beast\module\core\text</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\text\StringArray.h">
|
||||
<Filter>beast\module\core\text</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\text\StringPairArray.cpp">
|
||||
<Filter>beast\module\core\text</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\text\StringPairArray.h">
|
||||
<Filter>beast\module\core\text</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\threads\CriticalSection.h">
|
||||
<Filter>beast\module\core\threads</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\threads\ScopedLock.h">
|
||||
<Filter>beast\module\core\threads</Filter>
|
||||
</ClInclude>
|
||||
@@ -1305,9 +1116,6 @@
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\thread\DeadlineTimer.h">
|
||||
<Filter>beast\module\core\thread</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\module\core\thread\MutexTraits.h">
|
||||
<Filter>beast\module\core\thread</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\module\core\thread\Workers.cpp">
|
||||
<Filter>beast\module\core\thread</Filter>
|
||||
</ClCompile>
|
||||
@@ -1323,12 +1131,6 @@
|
||||
<ClInclude Include="..\..\src\beast\beast\net\detail\Parse.h">
|
||||
<Filter>beast\net\detail</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\net\DynamicBuffer.h">
|
||||
<Filter>beast\net</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\net\impl\DynamicBuffer.cpp">
|
||||
<Filter>beast\net\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\net\impl\IPAddressV4.cpp">
|
||||
<Filter>beast\net\impl</Filter>
|
||||
</ClCompile>
|
||||
@@ -1485,45 +1287,6 @@
|
||||
<ClCompile Include="..\..\src\beast\beast\streams\tests\basic_abstract_ostream.test.cpp">
|
||||
<Filter>beast\streams\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\Strings.h">
|
||||
<Filter>beast</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\CharacterFunctions.h">
|
||||
<Filter>beast\strings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\CharPointer_ASCII.h">
|
||||
<Filter>beast\strings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\CharPointer_UTF16.h">
|
||||
<Filter>beast\strings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\CharPointer_UTF32.h">
|
||||
<Filter>beast\strings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\CharPointer_UTF8.h">
|
||||
<Filter>beast\strings</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\strings\impl\CharacterFunctions.cpp">
|
||||
<Filter>beast\strings\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\strings\impl\String.cpp">
|
||||
<Filter>beast\strings\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\NewLine.h">
|
||||
<Filter>beast\strings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\String.h">
|
||||
<Filter>beast\strings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\StringCharPointerType.h">
|
||||
<Filter>beast\strings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\strings\StringFromNumber.h">
|
||||
<Filter>beast\strings</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\strings\Strings.unity.cpp">
|
||||
<Filter>beast\strings</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\Threads.h">
|
||||
<Filter>beast</Filter>
|
||||
</ClInclude>
|
||||
@@ -1539,21 +1302,9 @@
|
||||
<ClCompile Include="..\..\src\beast\beast\threads\impl\WaitableEvent.cpp">
|
||||
<Filter>beast\threads\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\ScopedWrapperContext.h">
|
||||
<Filter>beast\threads</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\semaphore.h">
|
||||
<Filter>beast\threads</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\SharedLockGuard.h">
|
||||
<Filter>beast\threads</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\SharedMutexAdapter.h">
|
||||
<Filter>beast\threads</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\SpinLock.h">
|
||||
<Filter>beast\threads</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\Stoppable.h">
|
||||
<Filter>beast\threads</Filter>
|
||||
</ClInclude>
|
||||
@@ -1563,12 +1314,6 @@
|
||||
<ClCompile Include="..\..\src\beast\beast\threads\Threads.unity.cpp">
|
||||
<Filter>beast\threads</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\TryLockGuard.h">
|
||||
<Filter>beast\threads</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\UnlockGuard.h">
|
||||
<Filter>beast\threads</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\beast\beast\threads\WaitableEvent.h">
|
||||
<Filter>beast\threads</Filter>
|
||||
</ClInclude>
|
||||
@@ -1653,9 +1398,6 @@
|
||||
<ClInclude Include="..\..\src\beast\beast\utility\tagged_integer.h">
|
||||
<Filter>beast\utility</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\beast\beast\utility\tests\bassert.test.cpp">
|
||||
<Filter>beast\utility\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\beast\beast\utility\tests\empty_base_optimization.test.cpp">
|
||||
<Filter>beast\utility\tests</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ARITHMETIC_H_INCLUDED
|
||||
#define BEAST_ARITHMETIC_H_INCLUDED
|
||||
|
||||
#include <beast/Config.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/** Constrains a value to keep it within a given range.
|
||||
|
||||
This will check that the specified value lies between the lower and upper bounds
|
||||
specified, and if not, will return the nearest value that would be in-range. Effectively,
|
||||
it's like calling bmax (lowerLimit, bmin (upperLimit, value)).
|
||||
|
||||
Note that it expects that lowerLimit <= upperLimit. If this isn't true,
|
||||
the results will be unpredictable.
|
||||
|
||||
@param lowerLimit the minimum value to return
|
||||
@param upperLimit the maximum value to return
|
||||
@param valueToConstrain the value to try to return
|
||||
@returns the closest value to valueToConstrain which lies between lowerLimit
|
||||
and upperLimit (inclusive)
|
||||
@see blimit0To, bmin, bmax
|
||||
*/
|
||||
template <typename Type>
|
||||
inline Type blimit (const Type lowerLimit,
|
||||
const Type upperLimit,
|
||||
const Type valueToConstrain) noexcept
|
||||
{
|
||||
// if these are in the wrong order, results are unpredictable.
|
||||
bassert (lowerLimit <= upperLimit);
|
||||
|
||||
return (valueToConstrain < lowerLimit) ? lowerLimit
|
||||
: ((upperLimit < valueToConstrain) ? upperLimit
|
||||
: valueToConstrain);
|
||||
}
|
||||
|
||||
/** Returns true if a value is at least zero, and also below a specified upper limit.
|
||||
This is basically a quicker way to write:
|
||||
@code valueToTest >= 0 && valueToTest < upperLimit
|
||||
@endcode
|
||||
*/
|
||||
template <typename Type>
|
||||
inline bool isPositiveAndBelow (Type valueToTest, Type upperLimit) noexcept
|
||||
{
|
||||
bassert (Type() <= upperLimit); // makes no sense to call this if the upper limit is itself below zero..
|
||||
return Type() <= valueToTest && valueToTest < upperLimit;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool isPositiveAndBelow (const int valueToTest, const int upperLimit) noexcept
|
||||
{
|
||||
bassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero..
|
||||
return static_cast <unsigned int> (valueToTest) < static_cast <unsigned int> (upperLimit);
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
||||
/** Handy function for getting the number of elements in a simple const C array.
|
||||
E.g.
|
||||
@code
|
||||
static int myArray[] = { 1, 2, 3 };
|
||||
|
||||
int numElements = numElementsInArray (myArray) // returns 3
|
||||
@endcode
|
||||
*/
|
||||
template <typename Type, int N>
|
||||
int numElementsInArray (Type (&array)[N])
|
||||
{
|
||||
(void) array; // (required to avoid a spurious warning in MS compilers)
|
||||
(void) sizeof (0[array]); // This line should cause an error if you pass an object with a user-defined subscript operator
|
||||
return N;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -40,37 +40,6 @@ template <typename Type>
|
||||
void zerostruct (Type& structure) noexcept
|
||||
{ memset (&structure, 0, sizeof (structure)); }
|
||||
|
||||
/** Delete an object pointer, and sets the pointer to null.
|
||||
|
||||
Remember that it's not good c++ practice to use delete directly - always try to use a std::unique_ptr
|
||||
or other automatic lifetime-management system rather than resorting to deleting raw pointers!
|
||||
*/
|
||||
template <typename Type>
|
||||
void deleteAndZero (Type& pointer)
|
||||
{ delete pointer; pointer = nullptr; }
|
||||
|
||||
/** A handy function which adds a number of bytes to any type of pointer and returns the result.
|
||||
This can be useful to avoid casting pointers to a char* and back when you want to move them by
|
||||
a specific number of bytes,
|
||||
*/
|
||||
template <typename Type, typename IntegerType>
|
||||
Type* addBytesToPointer (Type* pointer, IntegerType bytes) noexcept
|
||||
{ return (Type*) (((char*) pointer) + bytes); }
|
||||
|
||||
/** A handy function which returns the difference between any two pointers, in bytes.
|
||||
The address of the second pointer is subtracted from the first, and the difference in bytes is returned.
|
||||
*/
|
||||
template <typename Type1, typename Type2>
|
||||
int getAddressDifference (Type1* pointer1, Type2* pointer2) noexcept
|
||||
{ return (int) (((const char*) pointer1) - (const char*) pointer2); }
|
||||
|
||||
/** If a pointer is non-null, this returns a new copy of the object that it points to, or safely returns
|
||||
nullptr if the pointer is null.
|
||||
*/
|
||||
template <class Type>
|
||||
Type* createCopyIfNotNull (const Type* pointer)
|
||||
{ return pointer != nullptr ? new Type (*pointer) : nullptr; }
|
||||
|
||||
//==============================================================================
|
||||
#if BEAST_MAC || BEAST_IOS || DOXYGEN
|
||||
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_STRINGS_H_INCLUDED
|
||||
#define BEAST_STRINGS_H_INCLUDED
|
||||
|
||||
#include <beast/strings/String.h>
|
||||
#include <beast/strings/NewLine.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,15 +20,9 @@
|
||||
#ifndef BEAST_THREADS_H_INCLUDED
|
||||
#define BEAST_THREADS_H_INCLUDED
|
||||
|
||||
#include <beast/threads/UnlockGuard.h>
|
||||
#include <beast/threads/TryLockGuard.h>
|
||||
#include <beast/threads/SharedLockGuard.h>
|
||||
#include <beast/threads/SharedMutexAdapter.h>
|
||||
#include <beast/threads/SpinLock.h>
|
||||
#include <beast/threads/Stoppable.h>
|
||||
#include <beast/threads/Thread.h>
|
||||
#include <beast/threads/WaitableEvent.h>
|
||||
#include <beast/threads/ScopedWrapperContext.h>
|
||||
|
||||
#include <beast/threads/semaphore.h>
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#define BEAST_CHRONO_RELATIVETIME_H_INCLUDED
|
||||
|
||||
#include <beast/Config.h>
|
||||
#include <beast/strings/String.h>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
@@ -145,24 +144,6 @@ public:
|
||||
*/
|
||||
value_type inWeeks() const noexcept;
|
||||
|
||||
/** Returns a readable textual description of the time.
|
||||
|
||||
The exact format of the string returned will depend on
|
||||
the magnitude of the time - e.g.
|
||||
|
||||
"1 min 4 secs", "1 hr 45 mins", "2 weeks 5 days", "140 ms"
|
||||
|
||||
so that only the two most significant units are printed.
|
||||
|
||||
The returnValueForZeroTime value is the result that is returned if the
|
||||
length is zero. Depending on your application you might want to use this
|
||||
to return something more relevant like "empty" or "0 secs", etc.
|
||||
|
||||
@see inMilliseconds, inSeconds, inMinutes, inHours, inDays, inWeeks
|
||||
*/
|
||||
String getDescription (const String& returnValueForZeroTime = "0") const;
|
||||
std::string to_string () const;
|
||||
|
||||
template <typename Number>
|
||||
RelativeTime operator+ (Number seconds) const noexcept
|
||||
{ return RelativeTime (numSeconds + seconds); }
|
||||
@@ -204,12 +185,6 @@ RelativeTime operator+ (RelativeTime t1, RelativeTime t2) noexcept;
|
||||
/** Subtracts two RelativeTimes. */
|
||||
RelativeTime operator- (RelativeTime t1, RelativeTime t2) noexcept;
|
||||
|
||||
inline std::ostream& operator<< (std::ostream& os, RelativeTime const& diff)
|
||||
{
|
||||
os << diff.to_string();
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,16 +23,6 @@
|
||||
|
||||
#include <beast/chrono/RelativeTime.h>
|
||||
|
||||
// VFALCO TODO Migrate the localizable strings interfaces for this file
|
||||
|
||||
#ifndef NEEDS_TRANS
|
||||
#define NEEDS_TRANS(s) (s)
|
||||
#endif
|
||||
|
||||
#ifndef TRANS
|
||||
#define TRANS(s) (s)
|
||||
#endif
|
||||
|
||||
namespace beast {
|
||||
|
||||
RelativeTime::RelativeTime (const RelativeTime::value_type secs) noexcept
|
||||
@@ -175,86 +165,6 @@ bool operator<= (RelativeTime t1, RelativeTime t2) noexcept
|
||||
return t1.inSeconds() <= t2.inSeconds();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
static void translateTimeField (String& result, int n, const char* singular, const char* plural)
|
||||
{
|
||||
result << TRANS (String((n == 1) ? singular : plural))
|
||||
.replace (n == 1 ? "1" : "2", String (n))
|
||||
<< ' ';
|
||||
}
|
||||
|
||||
String RelativeTime::getDescription (const String& returnValueForZeroTime) const
|
||||
{
|
||||
if (numSeconds < 0.001 && numSeconds > -0.001)
|
||||
return returnValueForZeroTime;
|
||||
|
||||
String result;
|
||||
result.preallocateBytes (32);
|
||||
|
||||
if (numSeconds < 0)
|
||||
result << '-';
|
||||
|
||||
int fieldsShown = 0;
|
||||
int n = std::abs ((int) inWeeks());
|
||||
if (n > 0)
|
||||
{
|
||||
translateTimeField (result, n, NEEDS_TRANS("1 week"), NEEDS_TRANS("2 weeks"));
|
||||
++fieldsShown;
|
||||
}
|
||||
|
||||
n = std::abs ((int) inDays()) % 7;
|
||||
if (n > 0)
|
||||
{
|
||||
translateTimeField (result, n, NEEDS_TRANS("1 day"), NEEDS_TRANS("2 days"));
|
||||
++fieldsShown;
|
||||
}
|
||||
|
||||
if (fieldsShown < 2)
|
||||
{
|
||||
n = std::abs ((int) inHours()) % 24;
|
||||
if (n > 0)
|
||||
{
|
||||
translateTimeField (result, n, NEEDS_TRANS("1 hour"), NEEDS_TRANS("2 hours"));
|
||||
++fieldsShown;
|
||||
}
|
||||
|
||||
if (fieldsShown < 2)
|
||||
{
|
||||
n = std::abs ((int) inMinutes()) % 60;
|
||||
if (n > 0)
|
||||
{
|
||||
translateTimeField (result, n, NEEDS_TRANS("1 minute"), NEEDS_TRANS("2 minutes"));
|
||||
++fieldsShown;
|
||||
}
|
||||
|
||||
if (fieldsShown < 2)
|
||||
{
|
||||
n = std::abs ((int) inSeconds()) % 60;
|
||||
if (n > 0)
|
||||
{
|
||||
translateTimeField (result, n, NEEDS_TRANS("1 seconds"), NEEDS_TRANS("2 seconds"));
|
||||
++fieldsShown;
|
||||
}
|
||||
|
||||
if (fieldsShown == 0)
|
||||
{
|
||||
n = std::abs ((int) inMilliseconds()) % 1000;
|
||||
if (n > 0)
|
||||
result << n << ' ' << TRANS ("ms");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.trimEnd();
|
||||
}
|
||||
|
||||
std::string RelativeTime::to_string () const
|
||||
{
|
||||
return getDescription ().toStdString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if BEAST_WINDOWS
|
||||
|
||||
@@ -50,107 +50,6 @@
|
||||
# define BEAST_CONSTEXPR constexpr
|
||||
#endif
|
||||
|
||||
|
||||
// Debugging and assertion macros
|
||||
|
||||
#if BEAST_LOG_ASSERTIONS || BEAST_DEBUG
|
||||
#define beast_LogCurrentAssertion beast::logAssertion (__FILE__, __LINE__);
|
||||
#else
|
||||
#define beast_LogCurrentAssertion
|
||||
#endif
|
||||
|
||||
#if BEAST_IOS || BEAST_LINUX || BEAST_ANDROID || BEAST_PPC
|
||||
/** This will try to break into the debugger if the app is currently being debugged.
|
||||
If called by an app that's not being debugged, the behaiour isn't defined - it may crash or not, depending
|
||||
on the platform.
|
||||
@see bassert()
|
||||
*/
|
||||
# define beast_breakDebugger { ::kill (0, SIGTRAP); }
|
||||
#elif BEAST_USE_INTRINSICS
|
||||
# ifndef __INTEL_COMPILER
|
||||
# pragma intrinsic (__debugbreak)
|
||||
# endif
|
||||
# define beast_breakDebugger { __debugbreak(); }
|
||||
#elif BEAST_GCC || BEAST_MAC
|
||||
# if BEAST_NO_INLINE_ASM
|
||||
# define beast_breakDebugger { }
|
||||
# else
|
||||
# define beast_breakDebugger { asm ("int $3"); }
|
||||
# endif
|
||||
#else
|
||||
# define beast_breakDebugger { __asm int 3 }
|
||||
#endif
|
||||
|
||||
#if BEAST_CLANG && defined (__has_feature) && ! defined (BEAST_ANALYZER_NORETURN)
|
||||
# if __has_feature (attribute_analyzer_noreturn)
|
||||
inline void __attribute__((analyzer_noreturn)) beast_assert_noreturn() {}
|
||||
# define BEAST_ANALYZER_NORETURN beast_assert_noreturn();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef BEAST_ANALYZER_NORETURN
|
||||
#define BEAST_ANALYZER_NORETURN
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/** Report a fatal error message and terminate the application.
|
||||
Normally you won't call this directly.
|
||||
*/
|
||||
extern void beast_reportFatalError (char const* message, char const* fileName, int lineNumber);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BEAST_DEBUG || DOXYGEN
|
||||
|
||||
/** Writes a string to the standard error stream.
|
||||
This is only compiled in a debug build.
|
||||
*/
|
||||
#define BDBG(dbgtext) { \
|
||||
beast::String tempDbgBuf; \
|
||||
tempDbgBuf << dbgtext; \
|
||||
beast::outputDebugString (tempDbgBuf.toStdString ()); \
|
||||
}
|
||||
|
||||
#if 0
|
||||
/** This will always cause an assertion failure.
|
||||
It is only compiled in a debug build, (unless BEAST_LOG_ASSERTIONS is enabled for your build).
|
||||
@see bassert
|
||||
*/
|
||||
#define bassertfalse { beast_LogCurrentAssertion; if (beast::beast_isRunningUnderDebugger()) beast_breakDebugger; BEAST_ANALYZER_NORETURN }
|
||||
|
||||
/** Platform-independent assertion macro.
|
||||
This macro gets turned into a no-op when you're building with debugging turned off, so be
|
||||
careful that the expression you pass to it doesn't perform any actions that are vital for the
|
||||
correct behaviour of your program!
|
||||
@see bassertfalse
|
||||
*/
|
||||
#define bassert(expression) { if (! (expression)) beast_reportFatalError(#expression,__FILE__,__LINE__); }
|
||||
#else
|
||||
|
||||
#define bassertfalse assert(false)
|
||||
#define bassert(expression) assert(expression)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// If debugging is disabled, these dummy debug and assertion macros are used..
|
||||
|
||||
#define BDBG(dbgtext)
|
||||
#define bassertfalse { beast_LogCurrentAssertion }
|
||||
|
||||
# if BEAST_LOG_ASSERTIONS
|
||||
# define bassert(expression) { if (! (expression)) bassertfalse; }
|
||||
# else
|
||||
# define bassert(a) {}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if ! DOXYGEN
|
||||
@@ -195,17 +94,6 @@ extern void beast_reportFatalError (char const* message, char const* fileName, i
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if BEAST_ANDROID && ! DOXYGEN
|
||||
# define BEAST_MODAL_LOOPS_PERMITTED 0
|
||||
#elif ! defined (BEAST_MODAL_LOOPS_PERMITTED)
|
||||
/** Some operating environments don't provide a modal loop mechanism, so this
|
||||
flag can be used to disable any functions that try to run a modal loop.
|
||||
*/
|
||||
#define BEAST_MODAL_LOOPS_PERMITTED 1
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if BEAST_GCC
|
||||
# define BEAST_PACKED __attribute__((packed))
|
||||
#elif ! DOXYGEN
|
||||
@@ -260,11 +148,4 @@ extern void beast_reportFatalError (char const* message, char const* fileName, i
|
||||
# define BEAST_MOVE_CAST(type) type
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace beast {
|
||||
bool beast_isRunningUnderDebugger();
|
||||
void logAssertion (char const* file, int line);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CONFIG_CONTRACTCHECKS_H_INCLUDED
|
||||
#define BEAST_CONFIG_CONTRACTCHECKS_H_INCLUDED
|
||||
|
||||
// This file has to work when included in a C source file.
|
||||
|
||||
#if defined (fatal_error) || \
|
||||
defined (fatal_condition) || \
|
||||
defined (meets_condition) || \
|
||||
defined (meets_precondition) || \
|
||||
defined (meets_postcondition) || \
|
||||
defined (meets_invariant) || \
|
||||
defined (check_invariant)
|
||||
#error "Programming by contract macros cannot be overriden!"
|
||||
#endif
|
||||
|
||||
/** Report a fatal error message and terminate the application.
|
||||
This macro automatically fills in the file and line number
|
||||
Meets this declaration syntax:
|
||||
@code inline void fatal_error (char const* message); @endif
|
||||
@see FatalError
|
||||
*/
|
||||
#define fatal_error(message) beast_reportFatalError (message, __FILE__, __LINE__)
|
||||
|
||||
/** Reports a fatal error message type if the condition is false
|
||||
The condition is always evaluated regardless of settings.
|
||||
Meets this declaration syntax:
|
||||
@code inline void fatal_condition (bool condition, char const* category); @endcode
|
||||
*/
|
||||
#define fatal_condition(condition,category) static_cast <void> \
|
||||
(((!!(condition)) || (beast_reportFatalError ( \
|
||||
category " '" BEAST_STRINGIFY(condition) "' failed.", __FILE__, __LINE__), 0)))
|
||||
|
||||
/** Reports a fatal error message type if the condition is false
|
||||
The condition is always evaluated regardless of settings.
|
||||
Meets this declaration syntax:
|
||||
@code inline void fatal_condition (bool condition, char const* category); @endcode
|
||||
*/
|
||||
#define meets_condition(condition,category) static_cast <bool> \
|
||||
(((!!(condition)) || (beast_reportFatalError ( \
|
||||
category " '" BEAST_STRINGIFY(condition) "' failed.", __FILE__, __LINE__), false)))
|
||||
|
||||
/** Condition tests for programming by contract.
|
||||
The condition is always evaluated regardless of settings, and gets returned.
|
||||
Meets this declaration syntax:
|
||||
@code inline bool meets_condition (bool); @endcode
|
||||
*/
|
||||
/** @{ */
|
||||
#define meets_precondition(condition) meets_condition(condition,"Pre-condition")
|
||||
#define meets_postcondition(condition) meets_condition(condition,"Post-condition")
|
||||
#define meets_invariant(condition) meets_condition(condition,"Invariant")
|
||||
/** @} */
|
||||
|
||||
/** Condition tests for programming by contract.
|
||||
The condition is evaluated only if BEAST_DISABLE_CONTRACT_CHECKS is 0.
|
||||
Meets this declaration syntax:
|
||||
@code inline void check_condition (bool); @endcode
|
||||
@see BEAST_DISABLE_CONTRACT_CHECKS
|
||||
*/
|
||||
/** @{ */
|
||||
#if ! BEAST_DISABLE_CONTRACT_CHECKS
|
||||
# define check_invariant(condition) meets_invariant(condition)
|
||||
#else
|
||||
# define check_invariant(condition) ((void)0)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
@@ -218,7 +218,7 @@ private:
|
||||
}
|
||||
|
||||
// VFALCO TODO IPv6 support
|
||||
bassertfalse;
|
||||
assert(false);
|
||||
return boost::asio::ip::udp::endpoint (
|
||||
boost::asio::ip::address_v6 (), 0);
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_ASIO_BOOSTINCLUDES_H_INCLUDED
|
||||
#define BEAST_MODULE_ASIO_BOOSTINCLUDES_H_INCLUDED
|
||||
|
||||
// Make sure we take care of fixing boost::bind oddities first.
|
||||
#if !defined(BEAST_CORE_H_INCLUDED)
|
||||
#error core.h must be included before including this file
|
||||
#endif
|
||||
|
||||
// These should have already been set in your project, but
|
||||
// if you forgot then we will be optimistic and choose the latest.
|
||||
//
|
||||
#if BEAST_WIN32
|
||||
# ifndef _WIN32_WINNT
|
||||
# pragma message ("Warning: _WIN32_WINNT was not set in your project")
|
||||
# define _WIN32_WINNT 0x0600
|
||||
# endif
|
||||
# ifndef _VARIADIC_MAX
|
||||
# define _VARIADIC_MAX 10
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// work-around for broken <boost/get_pointer.hpp>
|
||||
#include <beast/boost/get_pointer.h>
|
||||
|
||||
#endif
|
||||
@@ -1,57 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/asio/HTTPField.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPField::HTTPField ()
|
||||
{
|
||||
}
|
||||
|
||||
HTTPField::HTTPField (String name_, String value_)
|
||||
: m_name (name_)
|
||||
, m_value (value_)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPField::HTTPField (HTTPField const& other)
|
||||
: m_name (other.m_name)
|
||||
, m_value (other.m_value)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPField& HTTPField::operator= (HTTPField const& other)
|
||||
{
|
||||
m_name = other.m_name;
|
||||
m_value = other.m_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
String HTTPField::name () const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
String HTTPField::value () const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_ASIO_HTTPFIELD_H_INCLUDED
|
||||
#define BEAST_MODULE_ASIO_HTTPFIELD_H_INCLUDED
|
||||
|
||||
#include <beast/strings/String.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A single header.
|
||||
The header is a field/value pair.
|
||||
Time complexity of copies is constant.
|
||||
*/
|
||||
class HTTPField
|
||||
{
|
||||
public:
|
||||
HTTPField ();
|
||||
HTTPField (String name_, String value_);
|
||||
HTTPField (HTTPField const& other);
|
||||
HTTPField& operator= (HTTPField const& other);
|
||||
String name () const;
|
||||
String value () const;
|
||||
|
||||
private:
|
||||
String m_name;
|
||||
String m_value;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,108 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/asio/HTTPHeaders.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPHeaders::HTTPHeaders ()
|
||||
{
|
||||
}
|
||||
|
||||
HTTPHeaders::HTTPHeaders (StringPairArray& fields)
|
||||
{
|
||||
m_fields.swapWith (fields);
|
||||
}
|
||||
|
||||
HTTPHeaders::HTTPHeaders (StringPairArray const& fields)
|
||||
: m_fields (fields)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPHeaders::HTTPHeaders (HTTPHeaders const& other)
|
||||
: m_fields (other.m_fields)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPHeaders& HTTPHeaders::operator= (HTTPHeaders const& other)
|
||||
{
|
||||
m_fields = other.m_fields;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool HTTPHeaders::empty () const
|
||||
{
|
||||
return m_fields.size () == 0;
|
||||
}
|
||||
|
||||
std::size_t HTTPHeaders::size () const
|
||||
{
|
||||
return m_fields.size ();
|
||||
}
|
||||
|
||||
HTTPField HTTPHeaders::at (int index) const
|
||||
{
|
||||
return HTTPField (m_fields.getAllKeys () [index],
|
||||
m_fields.getAllValues () [index]);
|
||||
}
|
||||
|
||||
HTTPField HTTPHeaders::operator[] (int index) const
|
||||
{
|
||||
return at (index);
|
||||
}
|
||||
|
||||
String HTTPHeaders::get (String const& field) const
|
||||
{
|
||||
return m_fields [field];
|
||||
}
|
||||
|
||||
String HTTPHeaders::operator[] (String const& field) const
|
||||
{
|
||||
return get (field);
|
||||
}
|
||||
|
||||
String HTTPHeaders::toString () const
|
||||
{
|
||||
String s;
|
||||
for (int i = 0; i < m_fields.size (); ++i)
|
||||
{
|
||||
HTTPField const field (at(i));
|
||||
s << field.name() << ": " << field.value() << newLine;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
std::map <std::string, std::string>
|
||||
HTTPHeaders::build_map() const
|
||||
{
|
||||
std::map <std::string, std::string> c;
|
||||
auto const& k (m_fields.getAllKeys());
|
||||
auto const& v (m_fields.getAllValues());
|
||||
for (std::size_t i = 0; i < m_fields.size(); ++i)
|
||||
{
|
||||
auto key (k[i].toStdString());
|
||||
auto const value (v[i].toStdString());
|
||||
std::transform (key.begin(), key.end(), key.begin(), ::tolower);
|
||||
c[key] = value;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_ASIO_HTTPHEADERS_H_INCLUDED
|
||||
#define BEAST_MODULE_ASIO_HTTPHEADERS_H_INCLUDED
|
||||
|
||||
#include <beast/module/asio/HTTPField.h>
|
||||
#include <beast/module/core/text/StringPairArray.h>
|
||||
#include <map>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A set of HTTP headers. */
|
||||
class HTTPHeaders
|
||||
{
|
||||
public:
|
||||
/** Construct an empty set of headers. */
|
||||
HTTPHeaders ();
|
||||
|
||||
/** Construct headers taking ownership of a field array.
|
||||
The callers value is overwritten.
|
||||
*/
|
||||
HTTPHeaders (StringPairArray& fields);
|
||||
|
||||
/** Construct a copy of headers from an array.*/
|
||||
HTTPHeaders (StringPairArray const& fields);
|
||||
|
||||
/** Construct a copy of headers. */
|
||||
HTTPHeaders (HTTPHeaders const& other);
|
||||
|
||||
/** Assign a copy of headers. */
|
||||
HTTPHeaders& operator= (HTTPHeaders const& other);
|
||||
|
||||
/** Returns `true` if the container is empty. */
|
||||
bool empty () const;
|
||||
|
||||
/** Returns the number of fields in the container. */
|
||||
std::size_t size () const;
|
||||
|
||||
/** Random access to fields by index. */
|
||||
/** @{ */
|
||||
HTTPField at (int index) const;
|
||||
HTTPField operator[] (int index) const;
|
||||
/** @} */
|
||||
|
||||
/** Associative access to fields by name.
|
||||
If the field is not present, an empty string is returned.
|
||||
*/
|
||||
/** @{ */
|
||||
String get (String const& field) const;
|
||||
String operator[] (String const& field) const;
|
||||
/** @} */
|
||||
|
||||
/** Outputs all the headers into one string. */
|
||||
String toString () const;
|
||||
|
||||
// VFALCO HACK to present the headers in a useful format
|
||||
std::map <std::string, std::string>
|
||||
build_map() const;
|
||||
|
||||
private:
|
||||
StringPairArray m_fields;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,56 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/asio/HTTPMessage.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPMessage::HTTPMessage (HTTPVersion const& version_,
|
||||
StringPairArray& fields,
|
||||
DynamicBuffer& body)
|
||||
: m_version (version_)
|
||||
, m_headers (fields)
|
||||
{
|
||||
m_body.swapWith (body);
|
||||
}
|
||||
|
||||
HTTPVersion const& HTTPMessage::version () const
|
||||
{
|
||||
return m_version;
|
||||
}
|
||||
|
||||
HTTPHeaders const& HTTPMessage::headers () const
|
||||
{
|
||||
return m_headers;
|
||||
}
|
||||
|
||||
DynamicBuffer const& HTTPMessage::body () const
|
||||
{
|
||||
return m_body;
|
||||
}
|
||||
|
||||
String HTTPMessage::toString () const
|
||||
{
|
||||
String s;
|
||||
s << "HTTP " << version().toString() << newLine;
|
||||
s << m_headers.toString ();
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_ASIO_HTTPMESSAGE_H_INCLUDED
|
||||
#define BEAST_MODULE_ASIO_HTTPMESSAGE_H_INCLUDED
|
||||
|
||||
#include <beast/module/asio/HTTPHeaders.h>
|
||||
#include <beast/module/asio/HTTPVersion.h>
|
||||
|
||||
#include <beast/smart_ptr/SharedObject.h>
|
||||
#include <beast/net/DynamicBuffer.h>
|
||||
#include <beast/module/core/text/StringPairArray.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A complete HTTP message.
|
||||
|
||||
This provides the information common to all HTTP messages, including
|
||||
the version, content body, and headers.
|
||||
Derived classes provide the request or response specific data.
|
||||
|
||||
Because a single HTTP message can be a fairly expensive object to
|
||||
make copies of, this is a SharedObject.
|
||||
|
||||
@see HTTPRequest, HTTPResponse
|
||||
*/
|
||||
class HTTPMessage : public SharedObject
|
||||
{
|
||||
public:
|
||||
/** Construct the common HTTP message parts from values.
|
||||
Ownership of the fields and body parameters are
|
||||
transferred from the caller.
|
||||
*/
|
||||
HTTPMessage (HTTPVersion const& version_,
|
||||
StringPairArray& fields,
|
||||
DynamicBuffer& body);
|
||||
|
||||
/** Returns the HTTP version of this message. */
|
||||
HTTPVersion const& version () const;
|
||||
|
||||
/** Returns the set of HTTP headers associated with this message. */
|
||||
HTTPHeaders const& headers () const;
|
||||
|
||||
/** Returns the content-body. */
|
||||
DynamicBuffer const& body () const;
|
||||
|
||||
/** Outputs all the HTTPMessage data excluding the body into a string. */
|
||||
String toString () const;
|
||||
|
||||
private:
|
||||
HTTPVersion m_version;
|
||||
HTTPHeaders m_headers;
|
||||
DynamicBuffer m_body;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,111 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/asio/HTTPParser.h>
|
||||
#include <beast/module/asio/HTTPParserImpl.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPParser::HTTPParser (Type type)
|
||||
: m_type (type)
|
||||
, m_impl (new HTTPParserImpl (
|
||||
(type == typeResponse) ? joyent::HTTP_RESPONSE : joyent::HTTP_REQUEST))
|
||||
{
|
||||
}
|
||||
|
||||
HTTPParser::~HTTPParser ()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned char HTTPParser::error () const
|
||||
{
|
||||
return m_impl->http_errno ();
|
||||
}
|
||||
|
||||
String HTTPParser::message () const
|
||||
{
|
||||
return m_impl->http_errno_message ();
|
||||
}
|
||||
|
||||
std::size_t HTTPParser::process (void const* buf, std::size_t bytes)
|
||||
{
|
||||
std::size_t const bytes_used (m_impl->process (buf, bytes));
|
||||
|
||||
if (m_impl->finished ())
|
||||
{
|
||||
if (m_type == typeRequest)
|
||||
{
|
||||
m_request = new HTTPRequest (
|
||||
m_impl->version (),
|
||||
m_impl->fields (),
|
||||
m_impl->body (),
|
||||
m_impl->method ());
|
||||
}
|
||||
else if (m_type == typeResponse)
|
||||
{
|
||||
m_response = new HTTPResponse (
|
||||
m_impl->version (),
|
||||
m_impl->fields (),
|
||||
m_impl->body (),
|
||||
m_impl->status_code ());
|
||||
}
|
||||
else
|
||||
{
|
||||
bassertfalse;
|
||||
}
|
||||
}
|
||||
|
||||
return bytes_used;
|
||||
}
|
||||
|
||||
void HTTPParser::process_eof ()
|
||||
{
|
||||
m_impl->process_eof ();
|
||||
}
|
||||
|
||||
bool HTTPParser::finished () const
|
||||
{
|
||||
return m_impl->finished();
|
||||
}
|
||||
|
||||
StringPairArray const& HTTPParser::fields () const
|
||||
{
|
||||
return m_impl->fields();
|
||||
}
|
||||
|
||||
bool HTTPParser::headersComplete () const
|
||||
{
|
||||
return m_impl->headers_complete();
|
||||
}
|
||||
|
||||
SharedPtr <HTTPRequest> const& HTTPParser::request ()
|
||||
{
|
||||
bassert (m_type == typeRequest);
|
||||
|
||||
return m_request;
|
||||
}
|
||||
|
||||
SharedPtr <HTTPResponse> const& HTTPParser::response ()
|
||||
{
|
||||
bassert (m_type == typeResponse);
|
||||
|
||||
return m_response;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_ASIO_HTTPPARSER_H_INCLUDED
|
||||
#define BEAST_MODULE_ASIO_HTTPPARSER_H_INCLUDED
|
||||
|
||||
#include <beast/module/asio/HTTPRequest.h>
|
||||
#include <beast/module/asio/HTTPResponse.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class HTTPParserImpl;
|
||||
|
||||
/** A parser for HTTPRequest and HTTPResponse objects. */
|
||||
class HTTPParser
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
typeRequest,
|
||||
typeResponse
|
||||
};
|
||||
|
||||
/** Construct a new parser for the specified HTTPMessage type. */
|
||||
explicit HTTPParser (Type type);
|
||||
|
||||
/** Destroy the parser. */
|
||||
~HTTPParser ();
|
||||
|
||||
/** Returns a non zero error code if parsing fails. */
|
||||
unsigned char error () const;
|
||||
|
||||
/** Returns the error message text when error is non zero. */
|
||||
String message () const;
|
||||
|
||||
/** Parse the buffer and return the amount used.
|
||||
Typically it is an error when this returns less than
|
||||
the amount passed in.
|
||||
*/
|
||||
std::size_t process (void const* buf, std::size_t bytes);
|
||||
|
||||
/** Notify the parser that eof was received.
|
||||
*/
|
||||
void process_eof ();
|
||||
|
||||
/** Returns `true` when parsing is successful and complete. */
|
||||
bool finished () const;
|
||||
|
||||
/** Peek at the header fields as they are being built.
|
||||
Only complete pairs will show up, never partial strings.
|
||||
*/
|
||||
StringPairArray const& fields () const;
|
||||
|
||||
/** Returns `true` if all the HTTP headers have been received. */
|
||||
bool headersComplete () const;
|
||||
|
||||
/** Return the HTTPRequest object produced from the parsiing.
|
||||
Only valid after finished returns `true`.
|
||||
*/
|
||||
SharedPtr <HTTPRequest> const& request ();
|
||||
|
||||
/** Return the HTTPResponse object produced from the parsing.
|
||||
Only valid after finished returns `true`.
|
||||
*/
|
||||
SharedPtr <HTTPResponse> const& response ();
|
||||
|
||||
protected:
|
||||
Type m_type;
|
||||
std::unique_ptr <HTTPParserImpl> m_impl;
|
||||
SharedPtr <HTTPRequest> m_request;
|
||||
SharedPtr <HTTPResponse> m_response;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,276 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_ASIO_HTTPPARSERIMPL_H_INCLUDED
|
||||
#define BEAST_MODULE_ASIO_HTTPPARSERIMPL_H_INCLUDED
|
||||
|
||||
#include <beast/http/impl/joyent_parser.h>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class HTTPParserImpl
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
stringReservation = 256
|
||||
};
|
||||
|
||||
explicit HTTPParserImpl (enum joyent::http_parser_type type)
|
||||
: m_finished (false)
|
||||
, m_was_value (false)
|
||||
, m_headersComplete (false)
|
||||
{
|
||||
m_settings.on_message_begin = &HTTPParserImpl::on_message_begin;
|
||||
m_settings.on_url = &HTTPParserImpl::on_url;
|
||||
m_settings.on_status = &HTTPParserImpl::on_status;
|
||||
m_settings.on_header_field = &HTTPParserImpl::on_header_field;
|
||||
m_settings.on_header_value = &HTTPParserImpl::on_header_value;
|
||||
m_settings.on_headers_complete = &HTTPParserImpl::on_headers_complete;
|
||||
m_settings.on_body = &HTTPParserImpl::on_body;
|
||||
m_settings.on_message_complete = &HTTPParserImpl::on_message_complete;
|
||||
|
||||
m_field.reserve (stringReservation);
|
||||
m_value.reserve (stringReservation);
|
||||
|
||||
joyent::http_parser_init (&m_parser, type);
|
||||
m_parser.data = this;
|
||||
}
|
||||
|
||||
~HTTPParserImpl ()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned char error () const
|
||||
{
|
||||
return m_parser.http_errno;
|
||||
}
|
||||
|
||||
String message () const
|
||||
{
|
||||
return String (joyent::http_errno_name (static_cast <
|
||||
enum joyent::http_errno> (m_parser.http_errno)));
|
||||
}
|
||||
|
||||
std::size_t process (void const* buf, std::size_t bytes)
|
||||
{
|
||||
return joyent::http_parser_execute (&m_parser,
|
||||
&m_settings, static_cast <char const*> (buf), bytes);
|
||||
}
|
||||
|
||||
void process_eof ()
|
||||
{
|
||||
joyent::http_parser_execute (&m_parser, &m_settings, nullptr, 0);
|
||||
}
|
||||
|
||||
bool finished () const
|
||||
{
|
||||
return m_finished;
|
||||
}
|
||||
|
||||
HTTPVersion version () const
|
||||
{
|
||||
return HTTPVersion (
|
||||
m_parser.http_major, m_parser.http_minor);
|
||||
}
|
||||
|
||||
// Only for HTTPResponse!
|
||||
unsigned short status_code () const
|
||||
{
|
||||
return m_parser.status_code;
|
||||
}
|
||||
|
||||
// Only for HTTPRequest!
|
||||
unsigned char method () const
|
||||
{
|
||||
return m_parser.method;
|
||||
}
|
||||
|
||||
unsigned char http_errno () const
|
||||
{
|
||||
return m_parser.http_errno;
|
||||
}
|
||||
|
||||
String http_errno_message () const
|
||||
{
|
||||
return String (joyent::http_errno_name (
|
||||
static_cast <enum joyent::http_errno> (
|
||||
m_parser.http_errno)));
|
||||
}
|
||||
|
||||
bool upgrade () const
|
||||
{
|
||||
return m_parser.upgrade != 0;
|
||||
}
|
||||
|
||||
StringPairArray& fields ()
|
||||
{
|
||||
return m_fields;
|
||||
}
|
||||
|
||||
bool headers_complete () const
|
||||
{
|
||||
return m_headersComplete;
|
||||
}
|
||||
|
||||
DynamicBuffer& body ()
|
||||
{
|
||||
return m_body;
|
||||
}
|
||||
|
||||
private:
|
||||
void addFieldValue ()
|
||||
{
|
||||
if (m_field.size () > 0 && m_value.size () > 0)
|
||||
m_fields.set (m_field, m_value);
|
||||
m_field.resize (0);
|
||||
m_value.resize (0);
|
||||
}
|
||||
|
||||
int onMessageBegin ()
|
||||
{
|
||||
int ec (0);
|
||||
return ec;
|
||||
}
|
||||
|
||||
int onUrl (char const*, std::size_t)
|
||||
{
|
||||
int ec (0);
|
||||
// This is for HTTP Request
|
||||
return ec;
|
||||
}
|
||||
|
||||
int onStatus ()
|
||||
{
|
||||
int ec (0);
|
||||
return ec;
|
||||
}
|
||||
|
||||
int onHeaderField (char const* at, std::size_t length)
|
||||
{
|
||||
int ec (0);
|
||||
if (m_was_value)
|
||||
{
|
||||
addFieldValue ();
|
||||
m_was_value = false;
|
||||
}
|
||||
m_field.append (at, length);
|
||||
return ec;
|
||||
}
|
||||
|
||||
int onHeaderValue (char const* at, std::size_t length)
|
||||
{
|
||||
int ec (0);
|
||||
m_value.append (at, length);
|
||||
m_was_value = true;
|
||||
return ec;
|
||||
}
|
||||
|
||||
int onHeadersComplete ()
|
||||
{
|
||||
m_headersComplete = true;
|
||||
int ec (0);
|
||||
addFieldValue ();
|
||||
return ec;
|
||||
}
|
||||
|
||||
int onBody (char const* at, std::size_t length)
|
||||
{
|
||||
m_body.commit (boost::asio::buffer_copy (
|
||||
m_body.prepare <boost::asio::mutable_buffer> (length),
|
||||
boost::asio::buffer (at, length)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int onMessageComplete ()
|
||||
{
|
||||
int ec (0);
|
||||
m_finished = true;
|
||||
return ec;
|
||||
}
|
||||
|
||||
private:
|
||||
static int on_message_begin (joyent::http_parser* parser)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onMessageBegin ();
|
||||
}
|
||||
|
||||
static int on_url (joyent::http_parser* parser, const char *at, size_t length)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onUrl (at, length);
|
||||
}
|
||||
|
||||
static int on_status (joyent::http_parser* parser,
|
||||
char const* /*at*/, size_t /*length*/)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onStatus ();
|
||||
}
|
||||
|
||||
static int on_header_field (joyent::http_parser* parser,
|
||||
const char *at, size_t length)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onHeaderField (at, length);
|
||||
}
|
||||
|
||||
static int on_header_value (joyent::http_parser* parser,
|
||||
const char *at, size_t length)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onHeaderValue (at, length);
|
||||
}
|
||||
|
||||
static int on_headers_complete (joyent::http_parser* parser)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onHeadersComplete ();
|
||||
}
|
||||
|
||||
static int on_body (joyent::http_parser* parser,
|
||||
const char *at, size_t length)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onBody (at, length);
|
||||
}
|
||||
|
||||
static int on_message_complete (joyent::http_parser* parser)
|
||||
{
|
||||
return static_cast <HTTPParserImpl*> (parser->data)->
|
||||
onMessageComplete ();
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_finished;
|
||||
joyent::http_parser_settings m_settings;
|
||||
joyent::http_parser m_parser;
|
||||
StringPairArray m_fields;
|
||||
bool m_was_value;
|
||||
std::string m_field;
|
||||
std::string m_value;
|
||||
bool m_headersComplete;
|
||||
DynamicBuffer m_body;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,47 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/asio/HTTPRequest.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPRequest::HTTPRequest (
|
||||
HTTPVersion const& version_,
|
||||
StringPairArray& fields,
|
||||
DynamicBuffer& body,
|
||||
unsigned short method_)
|
||||
: HTTPMessage (version_, fields, body)
|
||||
, m_method (method_)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned short HTTPRequest::method () const
|
||||
{
|
||||
return m_method;
|
||||
}
|
||||
|
||||
String HTTPRequest::toString () const
|
||||
{
|
||||
String s;
|
||||
s << "Method: " << String::fromNumber (method ()) << newLine;
|
||||
s << this->HTTPMessage::toString ();
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_ASIO_HTTPREQUEST_H_INCLUDED
|
||||
#define BEAST_MODULE_ASIO_HTTPREQUEST_H_INCLUDED
|
||||
|
||||
#include <beast/module/asio/HTTPMessage.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class HTTPRequest : public HTTPMessage
|
||||
{
|
||||
public:
|
||||
/** Construct a complete response from values.
|
||||
Ownership of the fields and body parameters are
|
||||
transferred from the caller.
|
||||
*/
|
||||
HTTPRequest (
|
||||
HTTPVersion const& version_,
|
||||
StringPairArray& fields,
|
||||
DynamicBuffer& body,
|
||||
unsigned short method_);
|
||||
|
||||
unsigned short method () const;
|
||||
|
||||
/** Convert the request into a string, excluding the body. */
|
||||
String toString () const;
|
||||
|
||||
private:
|
||||
unsigned short m_method;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,38 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/asio/HTTPRequestParser.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPRequestParser::HTTPRequestParser ()
|
||||
: HTTPParser (typeRequest)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPRequestParser::~HTTPRequestParser ()
|
||||
{
|
||||
}
|
||||
|
||||
SharedPtr <HTTPRequest> const& HTTPRequestParser::request ()
|
||||
{
|
||||
return m_request;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_ASIO_HTTPREQUESTPARSER_H_INCLUDED
|
||||
#define BEAST_MODULE_ASIO_HTTPREQUESTPARSER_H_INCLUDED
|
||||
|
||||
#include <beast/module/asio/HTTPParser.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A parser for HTTPRequest objects. */
|
||||
class HTTPRequestParser : public HTTPParser
|
||||
{
|
||||
public:
|
||||
/** Construct a new parser for the specified HTTPMessage type. */
|
||||
HTTPRequestParser ();
|
||||
|
||||
/** Destroy the parser. */
|
||||
~HTTPRequestParser ();
|
||||
|
||||
/** Return the HTTPRequest object produced from the parsing. */
|
||||
SharedPtr <HTTPRequest> const& request ();
|
||||
|
||||
private:
|
||||
//SharedPtr <HTTPRequest> m_request;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,47 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/asio/HTTPResponse.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPResponse::HTTPResponse (
|
||||
HTTPVersion const& version_,
|
||||
StringPairArray& fields,
|
||||
DynamicBuffer& body,
|
||||
unsigned short status_)
|
||||
: HTTPMessage (version_, fields, body)
|
||||
, m_status (status_)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned short HTTPResponse::status () const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
String HTTPResponse::toString () const
|
||||
{
|
||||
String s;
|
||||
s << "Status: " << String::fromNumber (status ()) << newLine;
|
||||
s << this->HTTPMessage::toString ();
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_ASIO_HTTPRESPONSE_H_INCLUDED
|
||||
#define BEAST_MODULE_ASIO_HTTPRESPONSE_H_INCLUDED
|
||||
|
||||
#include <beast/module/asio/HTTPMessage.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class HTTPResponse : public HTTPMessage
|
||||
{
|
||||
public:
|
||||
/** Construct a complete response from values.
|
||||
Ownership of the fields and body parameters are
|
||||
transferred from the caller.
|
||||
*/
|
||||
HTTPResponse (
|
||||
HTTPVersion const& version_,
|
||||
StringPairArray& fields,
|
||||
DynamicBuffer& body,
|
||||
unsigned short status_);
|
||||
|
||||
unsigned short status () const;
|
||||
|
||||
/** Convert the response into a string, excluding the body. */
|
||||
String toString () const;
|
||||
|
||||
private:
|
||||
unsigned short m_status;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,38 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/asio/HTTPResponseParser.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPResponseParser::HTTPResponseParser ()
|
||||
: HTTPParser (typeResponse)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPResponseParser::~HTTPResponseParser ()
|
||||
{
|
||||
}
|
||||
|
||||
SharedPtr <HTTPResponse> const& HTTPResponseParser::response ()
|
||||
{
|
||||
return m_response;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_ASIO_HTTPRESPONSEPARSER_H_INCLUDED
|
||||
#define BEAST_MODULE_ASIO_HTTPRESPONSEPARSER_H_INCLUDED
|
||||
|
||||
#include <beast/module/asio/HTTPParser.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A parser for HTTPResponse objects. */
|
||||
class HTTPResponseParser : public HTTPParser
|
||||
{
|
||||
public:
|
||||
/** Construct a new parser for the specified HTTPMessage type. */
|
||||
HTTPResponseParser ();
|
||||
|
||||
/** Destroy the parser. */
|
||||
~HTTPResponseParser ();
|
||||
|
||||
/** Return the HTTPResponse object produced from the parsing. */
|
||||
SharedPtr <HTTPResponse> const& response ();
|
||||
|
||||
private:
|
||||
//SharedPtr <HTTPResponse> m_response;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,97 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast {
|
||||
|
||||
HTTPVersion::HTTPVersion ()
|
||||
: m_major (0)
|
||||
, m_minor (0)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPVersion::HTTPVersion (unsigned short major_, unsigned short minor_)
|
||||
: m_major (major_)
|
||||
, m_minor (minor_)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPVersion::HTTPVersion (HTTPVersion const& other)
|
||||
: m_major (other.m_major)
|
||||
, m_minor (other.m_minor)
|
||||
{
|
||||
}
|
||||
|
||||
HTTPVersion& HTTPVersion::operator= (HTTPVersion const& other)
|
||||
{
|
||||
m_major = other.m_major;
|
||||
m_minor = other.m_minor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
String HTTPVersion::toString () const
|
||||
{
|
||||
return String::fromNumber (vmajor ()) + "." +
|
||||
String::fromNumber (vminor ());
|
||||
}
|
||||
|
||||
unsigned short HTTPVersion::vmajor () const
|
||||
{
|
||||
return m_major;
|
||||
}
|
||||
|
||||
unsigned short HTTPVersion::vminor () const
|
||||
{
|
||||
return m_minor;
|
||||
}
|
||||
|
||||
bool HTTPVersion::operator== (HTTPVersion const& rhs) const
|
||||
{
|
||||
return (m_major == rhs.m_major) && (m_minor == rhs.m_minor);
|
||||
}
|
||||
|
||||
bool HTTPVersion::operator!= (HTTPVersion const& rhs) const
|
||||
{
|
||||
return (m_major != rhs.m_major) || (m_minor != rhs.m_minor);
|
||||
}
|
||||
|
||||
bool HTTPVersion::operator> (HTTPVersion const& rhs) const
|
||||
{
|
||||
return (m_major > rhs.m_major) ||
|
||||
((m_major == rhs.m_major) && (m_minor > rhs.m_minor));
|
||||
}
|
||||
|
||||
bool HTTPVersion::operator>= (HTTPVersion const& rhs) const
|
||||
{
|
||||
return (m_major > rhs.m_major) ||
|
||||
((m_major == rhs.m_major) && (m_minor >= rhs.m_minor));
|
||||
}
|
||||
|
||||
bool HTTPVersion::operator< (HTTPVersion const& rhs) const
|
||||
{
|
||||
return (m_major < rhs.m_major) ||
|
||||
((m_major == rhs.m_major) && (m_minor < rhs.m_minor));
|
||||
}
|
||||
|
||||
bool HTTPVersion::operator<= (HTTPVersion const& rhs) const
|
||||
{
|
||||
return (m_major < rhs.m_major) ||
|
||||
((m_major == rhs.m_major) && (m_minor <= rhs.m_minor));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_ASIO_HTTPVERSION_H_INCLUDED
|
||||
#define BEAST_MODULE_ASIO_HTTPVERSION_H_INCLUDED
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** The HTTP version. This is the major.minor version number. */
|
||||
class HTTPVersion
|
||||
{
|
||||
public:
|
||||
HTTPVersion ();
|
||||
HTTPVersion (unsigned short major_, unsigned short minor_);
|
||||
HTTPVersion (HTTPVersion const& other);
|
||||
HTTPVersion& operator= (HTTPVersion const& other);
|
||||
String toString () const;
|
||||
unsigned short vmajor () const;
|
||||
unsigned short vminor () const;
|
||||
bool operator== (HTTPVersion const& rhs) const;
|
||||
bool operator!= (HTTPVersion const& rhs) const;
|
||||
bool operator> (HTTPVersion const& rhs) const;
|
||||
bool operator>= (HTTPVersion const& rhs) const;
|
||||
bool operator< (HTTPVersion const& rhs) const;
|
||||
bool operator<= (HTTPVersion const& rhs) const;
|
||||
|
||||
private:
|
||||
unsigned short m_major;
|
||||
unsigned short m_minor;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,40 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_ASIO_OPENSSLINCLUDES_H_INCLUDED
|
||||
#define BEAST_MODULE_ASIO_OPENSSLINCLUDES_H_INCLUDED
|
||||
|
||||
#define OPENSSL_THREAD_DEFINES
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Configure our settings based on what we find
|
||||
//
|
||||
#if defined(OPENSSL_THREADS)
|
||||
# ifndef BEAST_OPENSSL_MULTITHREADED
|
||||
# define BEAST_OPENSSL_MULTITHREADED 1
|
||||
# endif
|
||||
#else
|
||||
# ifndef BEAST_OPENSSL_MULTITHREADED
|
||||
# define BEAST_OPENSSL_MULTITHREADED 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,32 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
|
||||
#include <beast/module/asio/HTTPField.cpp>
|
||||
#include <beast/module/asio/HTTPHeaders.cpp>
|
||||
#include <beast/module/asio/HTTPMessage.cpp>
|
||||
#include <beast/module/asio/HTTPRequest.cpp>
|
||||
#include <beast/module/asio/HTTPResponse.cpp>
|
||||
#include <beast/module/asio/HTTPVersion.cpp>
|
||||
#include <beast/module/asio/HTTPParser.cpp>
|
||||
#include <beast/module/asio/HTTPRequestParser.cpp>
|
||||
#include <beast/module/asio/HTTPResponseParser.cpp>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,135 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_CONTAINERS_ARRAYALLOCATIONBASE_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_CONTAINERS_ARRAYALLOCATIONBASE_H_INCLUDED
|
||||
|
||||
#include <beast/HeapBlock.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Implements some basic array storage allocation functions.
|
||||
|
||||
This class isn't really for public use - it's used by the other
|
||||
array classes, but might come in handy for some purposes.
|
||||
|
||||
It inherits from a critical section class to allow the arrays to use
|
||||
the "empty base class optimisation" pattern to reduce their footprint.
|
||||
|
||||
@see Array, SharedObjectArray
|
||||
*/
|
||||
template <class ElementType, class TypeOfCriticalSectionToUse>
|
||||
class ArrayAllocationBase
|
||||
: public TypeOfCriticalSectionToUse
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty array. */
|
||||
ArrayAllocationBase() noexcept
|
||||
: numAllocated (0)
|
||||
{
|
||||
}
|
||||
|
||||
/** Destructor. */
|
||||
~ArrayAllocationBase() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
ArrayAllocationBase (ArrayAllocationBase<ElementType, TypeOfCriticalSectionToUse>&& other) noexcept
|
||||
: elements (static_cast <HeapBlock <ElementType>&&> (other.elements)),
|
||||
numAllocated (other.numAllocated)
|
||||
{
|
||||
}
|
||||
|
||||
ArrayAllocationBase& operator= (ArrayAllocationBase<ElementType, TypeOfCriticalSectionToUse>&& other) noexcept
|
||||
{
|
||||
elements = static_cast <HeapBlock <ElementType>&&> (other.elements);
|
||||
numAllocated = other.numAllocated;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
/** Changes the amount of storage allocated.
|
||||
|
||||
This will retain any data currently held in the array, and either add or
|
||||
remove extra space at the end.
|
||||
|
||||
@param numElements the number of elements that are needed
|
||||
*/
|
||||
void setAllocatedSize (const int numElements)
|
||||
{
|
||||
if (numAllocated != numElements)
|
||||
{
|
||||
if (numElements > 0)
|
||||
elements.reallocate ((size_t) numElements);
|
||||
else
|
||||
elements.free_up();
|
||||
|
||||
numAllocated = numElements;
|
||||
}
|
||||
}
|
||||
|
||||
/** Increases the amount of storage allocated if it is less than a given amount.
|
||||
|
||||
This will retain any data currently held in the array, but will add
|
||||
extra space at the end to make sure there it's at least as big as the size
|
||||
passed in. If it's already bigger, no action is taken.
|
||||
|
||||
@param minNumElements the minimum number of elements that are needed
|
||||
*/
|
||||
void ensureAllocatedSize (const int minNumElements)
|
||||
{
|
||||
if (minNumElements > numAllocated)
|
||||
setAllocatedSize ((minNumElements + minNumElements / 2 + 8) & ~7);
|
||||
|
||||
bassert (numAllocated <= 0 || elements != nullptr);
|
||||
}
|
||||
|
||||
/** Minimises the amount of storage allocated so that it's no more than
|
||||
the given number of elements.
|
||||
*/
|
||||
void shrinkToNoMoreThan (const int maxNumElements)
|
||||
{
|
||||
if (maxNumElements < numAllocated)
|
||||
setAllocatedSize (maxNumElements);
|
||||
}
|
||||
|
||||
/** Swap the contents of two objects. */
|
||||
void swapWith (ArrayAllocationBase <ElementType, TypeOfCriticalSectionToUse>& other) noexcept
|
||||
{
|
||||
elements.swapWith (other.elements);
|
||||
std::swap (numAllocated, other.numAllocated);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
HeapBlock <ElementType> elements;
|
||||
int numAllocated;
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_ARRAYALLOCATIONBASE_H_INCLUDED
|
||||
@@ -1,195 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_CONTAINERS_ELEMENTCOMPARATOR_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_CONTAINERS_ELEMENTCOMPARATOR_H_INCLUDED
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace beast {
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
/** This is an internal helper class which converts a beast ElementComparator style
|
||||
class (using a "compareElements" method) into a class that's compatible with
|
||||
std::sort (i.e. using an operator() to compare the elements)
|
||||
*/
|
||||
template <typename ElementComparator>
|
||||
struct SortFunctionConverter
|
||||
{
|
||||
SortFunctionConverter (ElementComparator& e) : comparator (e) {}
|
||||
|
||||
template <typename Type>
|
||||
bool operator() (Type a, Type b) { return comparator.compareElements (a, b) < 0; }
|
||||
|
||||
private:
|
||||
ElementComparator& comparator;
|
||||
SortFunctionConverter& operator= (const SortFunctionConverter&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Sorts a range of elements in an array.
|
||||
|
||||
The comparator object that is passed-in must define a public method with the following
|
||||
signature:
|
||||
@code
|
||||
int compareElements (ElementType first, ElementType second);
|
||||
@endcode
|
||||
|
||||
..and this method must return:
|
||||
- a value of < 0 if the first comes before the second
|
||||
- a value of 0 if the two objects are equivalent
|
||||
- a value of > 0 if the second comes before the first
|
||||
|
||||
To improve performance, the compareElements() method can be declared as static or const.
|
||||
|
||||
@param comparator an object which defines a compareElements() method
|
||||
@param array the array to sort
|
||||
@param firstElement the index of the first element of the range to be sorted
|
||||
@param lastElement the index of the last element in the range that needs
|
||||
sorting (this is inclusive)
|
||||
@param retainOrderOfEquivalentItems if true, the order of items that the
|
||||
comparator deems the same will be maintained - this will be
|
||||
a slower algorithm than if they are allowed to be moved around.
|
||||
|
||||
@see sortArrayRetainingOrder
|
||||
*/
|
||||
template <class ElementType, class ElementComparator>
|
||||
static void sortArray (ElementComparator& comparator,
|
||||
ElementType* const array,
|
||||
int firstElement,
|
||||
int lastElement,
|
||||
const bool retainOrderOfEquivalentItems)
|
||||
{
|
||||
SortFunctionConverter<ElementComparator> converter (comparator);
|
||||
|
||||
if (retainOrderOfEquivalentItems)
|
||||
std::stable_sort (array + firstElement, array + lastElement + 1, converter);
|
||||
else
|
||||
std::sort (array + firstElement, array + lastElement + 1, converter);
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Searches a sorted array of elements, looking for the index at which a specified value
|
||||
should be inserted for it to be in the correct order.
|
||||
|
||||
The comparator object that is passed-in must define a public method with the following
|
||||
signature:
|
||||
@code
|
||||
int compareElements (ElementType first, ElementType second);
|
||||
@endcode
|
||||
|
||||
..and this method must return:
|
||||
- a value of < 0 if the first comes before the second
|
||||
- a value of 0 if the two objects are equivalent
|
||||
- a value of > 0 if the second comes before the first
|
||||
|
||||
To improve performance, the compareElements() method can be declared as static or const.
|
||||
|
||||
@param comparator an object which defines a compareElements() method
|
||||
@param array the array to search
|
||||
@param newElement the value that is going to be inserted
|
||||
@param firstElement the index of the first element to search
|
||||
@param lastElement the index of the last element in the range (this is non-inclusive)
|
||||
*/
|
||||
template <class ElementType, class ElementComparator>
|
||||
static int findInsertIndexInSortedArray (ElementComparator& comparator,
|
||||
ElementType* const array,
|
||||
const ElementType newElement,
|
||||
int firstElement,
|
||||
int lastElement)
|
||||
{
|
||||
bassert (firstElement <= lastElement);
|
||||
|
||||
(void) comparator; // if you pass in an object with a static compareElements() method, this
|
||||
// avoids getting warning messages about the parameter being unused
|
||||
|
||||
while (firstElement < lastElement)
|
||||
{
|
||||
if (comparator.compareElements (newElement, array [firstElement]) == 0)
|
||||
{
|
||||
++firstElement;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int halfway = (firstElement + lastElement) >> 1;
|
||||
|
||||
if (halfway == firstElement)
|
||||
{
|
||||
if (comparator.compareElements (newElement, array [halfway]) >= 0)
|
||||
++firstElement;
|
||||
|
||||
break;
|
||||
}
|
||||
else if (comparator.compareElements (newElement, array [halfway]) >= 0)
|
||||
{
|
||||
firstElement = halfway;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastElement = halfway;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return firstElement;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A simple ElementComparator class that can be used to sort an array of
|
||||
objects that support the '<' operator.
|
||||
|
||||
This will work for primitive types and objects that implement operator<().
|
||||
|
||||
Example: @code
|
||||
Array <int> myArray;
|
||||
DefaultElementComparator<int> sorter;
|
||||
myArray.sort (sorter);
|
||||
@endcode
|
||||
|
||||
@see ElementComparator
|
||||
*/
|
||||
template <class ElementType>
|
||||
class DefaultElementComparator
|
||||
{
|
||||
private:
|
||||
using ParameterType = ElementType;
|
||||
|
||||
public:
|
||||
static int compareElements (ParameterType first, ParameterType second)
|
||||
{
|
||||
return (first < second) ? -1 : ((second < first) ? 1 : 0);
|
||||
}
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
// TargetPlatform.h should not use anything from BeastConfig.h
|
||||
#include <beast/Config.h>
|
||||
#include <beast/config/ContractChecks.h>
|
||||
|
||||
#if BEAST_MSVC
|
||||
# pragma warning (disable: 4251) // (DLL build warning, must be disabled before pushing the warning state)
|
||||
@@ -41,12 +40,10 @@
|
||||
|
||||
// New header-only library modeled more closely according to boost
|
||||
#include <beast/SmartPtr.h>
|
||||
#include <beast/Arithmetic.h>
|
||||
#include <beast/ByteOrder.h>
|
||||
#include <beast/HeapBlock.h>
|
||||
#include <beast/Memory.h>
|
||||
#include <beast/Intrusive.h>
|
||||
#include <beast/Strings.h>
|
||||
#include <beast/Threads.h>
|
||||
|
||||
#include <beast/utility/Debug.h>
|
||||
@@ -55,90 +52,14 @@
|
||||
|
||||
#include <beast/module/core/system/StandardIncludes.h>
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
class InputStream;
|
||||
class OutputStream;
|
||||
class FileInputStream;
|
||||
class FileOutputStream;
|
||||
|
||||
} // beast
|
||||
|
||||
// Order matters, since headers don't have their own #include lines.
|
||||
// Add new includes to the bottom.
|
||||
|
||||
#include <beast/module/core/time/Time.h>
|
||||
#include <beast/module/core/threads/ScopedLock.h>
|
||||
#include <beast/module/core/threads/CriticalSection.h>
|
||||
#include <beast/module/core/containers/ElementComparator.h>
|
||||
|
||||
// If the MSVC debug heap headers were included, disable
|
||||
// the macros during the juce include since they conflict.
|
||||
#ifdef _CRTDBG_MAP_ALLOC
|
||||
#pragma push_macro("calloc")
|
||||
#pragma push_macro("free")
|
||||
#pragma push_macro("malloc")
|
||||
#pragma push_macro("realloc")
|
||||
#pragma push_macro("_recalloc")
|
||||
#pragma push_macro("_aligned_free")
|
||||
#pragma push_macro("_aligned_malloc")
|
||||
#pragma push_macro("_aligned_offset_malloc")
|
||||
#pragma push_macro("_aligned_realloc")
|
||||
#pragma push_macro("_aligned_recalloc")
|
||||
#pragma push_macro("_aligned_offset_realloc")
|
||||
#pragma push_macro("_aligned_offset_recalloc")
|
||||
#pragma push_macro("_aligned_msize")
|
||||
#undef calloc
|
||||
#undef free
|
||||
#undef malloc
|
||||
#undef realloc
|
||||
#undef _recalloc
|
||||
#undef _aligned_free
|
||||
#undef _aligned_malloc
|
||||
#undef _aligned_offset_malloc
|
||||
#undef _aligned_realloc
|
||||
#undef _aligned_recalloc
|
||||
#undef _aligned_offset_realloc
|
||||
#undef _aligned_offset_recalloc
|
||||
#undef _aligned_msize
|
||||
#endif
|
||||
#include <beast/module/core/containers/ArrayAllocationBase.h>
|
||||
#ifdef _CRTDBG_MAP_ALLOC
|
||||
#pragma pop_macro("_aligned_msize")
|
||||
#pragma pop_macro("_aligned_offset_recalloc")
|
||||
#pragma pop_macro("_aligned_offset_realloc")
|
||||
#pragma pop_macro("_aligned_recalloc")
|
||||
#pragma pop_macro("_aligned_realloc")
|
||||
#pragma pop_macro("_aligned_offset_malloc")
|
||||
#pragma pop_macro("_aligned_malloc")
|
||||
#pragma pop_macro("_aligned_free")
|
||||
#pragma pop_macro("_recalloc")
|
||||
#pragma pop_macro("realloc")
|
||||
#pragma pop_macro("malloc")
|
||||
#pragma pop_macro("free")
|
||||
#pragma pop_macro("calloc")
|
||||
#endif
|
||||
|
||||
#include <beast/module/core/containers/Array.h>
|
||||
|
||||
#include <beast/module/core/misc/Result.h>
|
||||
#include <beast/module/core/text/StringArray.h>
|
||||
#include <beast/module/core/memory/MemoryBlock.h>
|
||||
#include <beast/module/core/files/File.h>
|
||||
|
||||
#include <beast/module/core/thread/MutexTraits.h>
|
||||
#include <beast/module/core/diagnostic/FatalError.h>
|
||||
#include <beast/module/core/text/LexicalCast.h>
|
||||
#include <beast/module/core/logging/Logger.h>
|
||||
#include <beast/module/core/text/StringPairArray.h>
|
||||
#include <beast/module/core/files/DirectoryIterator.h>
|
||||
#include <beast/module/core/streams/InputStream.h>
|
||||
#include <beast/module/core/files/FileInputStream.h>
|
||||
#include <beast/module/core/streams/InputSource.h>
|
||||
#include <beast/module/core/streams/OutputStream.h>
|
||||
#include <beast/module/core/files/FileOutputStream.h>
|
||||
#include <beast/module/core/streams/MemoryOutputStream.h>
|
||||
|
||||
#include <beast/module/core/system/SystemStats.h>
|
||||
#include <beast/module/core/diagnostic/SemanticVersion.h>
|
||||
|
||||
@@ -134,24 +134,9 @@
|
||||
#include <beast/module/core/diagnostic/SemanticVersion.cpp>
|
||||
#include <beast/module/core/diagnostic/UnitTestUtilities.cpp>
|
||||
|
||||
#include <beast/module/core/files/DirectoryIterator.cpp>
|
||||
#include <beast/module/core/files/File.cpp>
|
||||
#include <beast/module/core/files/FileInputStream.cpp>
|
||||
#include <beast/module/core/files/FileOutputStream.cpp>
|
||||
|
||||
#include <beast/module/core/memory/MemoryBlock.cpp>
|
||||
|
||||
#include <beast/module/core/misc/Result.cpp>
|
||||
|
||||
#include <beast/module/core/streams/InputStream.cpp>
|
||||
#include <beast/module/core/streams/MemoryOutputStream.cpp>
|
||||
#include <beast/module/core/streams/OutputStream.cpp>
|
||||
|
||||
#include <beast/module/core/system/SystemStats.cpp>
|
||||
|
||||
#include <beast/module/core/text/LexicalCast.cpp>
|
||||
#include <beast/module/core/text/StringArray.cpp>
|
||||
#include <beast/module/core/text/StringPairArray.cpp>
|
||||
|
||||
#include <beast/module/core/thread/DeadlineTimer.cpp>
|
||||
#include <beast/module/core/thread/Workers.cpp>
|
||||
@@ -166,26 +151,16 @@
|
||||
#include "native/android_JNIHelpers.h"
|
||||
#endif
|
||||
|
||||
#if ! BEAST_WINDOWS
|
||||
#include <beast/module/core/native/posix_SharedCode.h>
|
||||
#endif
|
||||
|
||||
#if BEAST_MAC || BEAST_IOS
|
||||
#include <beast/module/core/native/mac_Files.mm>
|
||||
#include <beast/module/core/native/mac_Strings.mm>
|
||||
#include <beast/module/core/native/mac_SystemStats.mm>
|
||||
|
||||
#elif BEAST_WINDOWS
|
||||
#include <beast/module/core/native/win32_Files.cpp>
|
||||
#include <beast/module/core/native/win32_SystemStats.cpp>
|
||||
#include <beast/module/core/native/win32_Threads.cpp>
|
||||
|
||||
#elif BEAST_LINUX
|
||||
#include <beast/module/core/native/linux_Files.cpp>
|
||||
#include <beast/module/core/native/linux_SystemStats.cpp>
|
||||
|
||||
#elif BEAST_BSD
|
||||
#include <beast/module/core/native/bsd_Files.cpp>
|
||||
#include <beast/module/core/native/bsd_SystemStats.cpp>
|
||||
|
||||
#elif BEAST_ANDROID
|
||||
@@ -196,17 +171,6 @@
|
||||
|
||||
#endif
|
||||
|
||||
// Has to be outside the beast namespace
|
||||
extern "C" {
|
||||
void beast_reportFatalError (char const* message, char const* fileName, int lineNumber)
|
||||
{
|
||||
if (beast::beast_isRunningUnderDebugger())
|
||||
beast_breakDebugger;
|
||||
beast::FatalError (message, fileName, lineNumber);
|
||||
BEAST_ANALYZER_NORETURN
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _CRTDBG_MAP_ALLOC
|
||||
#pragma pop_macro("calloc")
|
||||
#pragma pop_macro("free")
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#ifndef BEAST_MODULE_CORE_DIAGNOSTIC_FATALERROR_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_DIAGNOSTIC_FATALERROR_H_INCLUDED
|
||||
|
||||
#include <beast/strings/String.h>
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <beast/module/core/text/LexicalCast.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -291,7 +292,7 @@ int compare (SemanticVersion const& lhs, SemanticVersion const& rhs)
|
||||
|
||||
if (isNumeric (left))
|
||||
{
|
||||
bassert (isNumeric (right));
|
||||
assert(isNumeric (right));
|
||||
|
||||
int const iLeft (lexicalCastThrow <int> (left));
|
||||
int const iRight (lexicalCastThrow <int> (right));
|
||||
@@ -303,7 +304,7 @@ int compare (SemanticVersion const& lhs, SemanticVersion const& rhs)
|
||||
}
|
||||
else
|
||||
{
|
||||
bassert (! isNumeric (right));
|
||||
assert (! isNumeric (right));
|
||||
|
||||
int result = left.compare (right);
|
||||
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace beast {
|
||||
|
||||
static StringArray parseWildcards (const String& pattern)
|
||||
{
|
||||
StringArray s;
|
||||
s.addTokens (pattern, ";,", "\"'");
|
||||
s.trim();
|
||||
s.removeEmptyStrings();
|
||||
return s;
|
||||
}
|
||||
|
||||
static bool fileMatches (const StringArray& wildCards, const String& filename)
|
||||
{
|
||||
for (int i = 0; i < wildCards.size(); ++i)
|
||||
if (filename.matchesWildcard (wildCards[i], ! File::areFileNamesCaseSensitive()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DirectoryIterator::DirectoryIterator (const File& directory, bool recursive,
|
||||
const String& pattern, const int type)
|
||||
: wildCards (parseWildcards (pattern)),
|
||||
fileFinder (directory, (recursive || wildCards.size() > 1) ? "*" : pattern),
|
||||
wildCard (pattern),
|
||||
path (File::addTrailingSeparator (directory.getFullPathName())),
|
||||
index (-1),
|
||||
totalNumFiles (-1),
|
||||
whatToLookFor (type),
|
||||
isRecursive (recursive),
|
||||
hasBeenAdvanced (false)
|
||||
{
|
||||
// you have to specify the type of files you're looking for!
|
||||
bassert ((type & (File::findFiles | File::findDirectories)) != 0);
|
||||
bassert (type > 0 && type <= 7);
|
||||
}
|
||||
|
||||
DirectoryIterator::~DirectoryIterator()
|
||||
{
|
||||
}
|
||||
|
||||
bool DirectoryIterator::next()
|
||||
{
|
||||
return next (nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
bool DirectoryIterator::next (bool* const isDirResult, bool* const isHiddenResult, std::int64_t* const fileSize,
|
||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
|
||||
{
|
||||
hasBeenAdvanced = true;
|
||||
|
||||
if (subIterator != nullptr)
|
||||
{
|
||||
if (subIterator->next (isDirResult, isHiddenResult, fileSize, modTime, creationTime, isReadOnly))
|
||||
return true;
|
||||
|
||||
subIterator = nullptr;
|
||||
}
|
||||
|
||||
String filename;
|
||||
bool isDirectory, isHidden = false;
|
||||
|
||||
while (fileFinder.next (filename, &isDirectory,
|
||||
(isHiddenResult != nullptr || (whatToLookFor & File::ignoreHiddenFiles) != 0) ? &isHidden : nullptr,
|
||||
fileSize, modTime, creationTime, isReadOnly))
|
||||
{
|
||||
++index;
|
||||
|
||||
if (! filename.containsOnly ("."))
|
||||
{
|
||||
bool matches = false;
|
||||
|
||||
if (isDirectory)
|
||||
{
|
||||
if (isRecursive && ((whatToLookFor & File::ignoreHiddenFiles) == 0 || ! isHidden))
|
||||
subIterator = std::make_unique <DirectoryIterator> (
|
||||
File::createFileWithoutCheckingPath (path + filename),
|
||||
true, wildCard, whatToLookFor);
|
||||
|
||||
matches = (whatToLookFor & File::findDirectories) != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
matches = (whatToLookFor & File::findFiles) != 0;
|
||||
}
|
||||
|
||||
// if we're not relying on the OS iterator to do the wildcard match, do it now..
|
||||
if (matches && (isRecursive || wildCards.size() > 1))
|
||||
matches = fileMatches (wildCards, filename);
|
||||
|
||||
if (matches && (whatToLookFor & File::ignoreHiddenFiles) != 0)
|
||||
matches = ! isHidden;
|
||||
|
||||
if (matches)
|
||||
{
|
||||
currentFile = File::createFileWithoutCheckingPath (path + filename);
|
||||
if (isHiddenResult != nullptr) *isHiddenResult = isHidden;
|
||||
if (isDirResult != nullptr) *isDirResult = isDirectory;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (subIterator != nullptr)
|
||||
return next (isDirResult, isHiddenResult, fileSize, modTime, creationTime, isReadOnly);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const File& DirectoryIterator::getFile() const
|
||||
{
|
||||
if (subIterator != nullptr && subIterator->hasBeenAdvanced)
|
||||
return subIterator->getFile();
|
||||
|
||||
// You need to call DirectoryIterator::next() before asking it for the file that it found!
|
||||
bassert (hasBeenAdvanced);
|
||||
|
||||
return currentFile;
|
||||
}
|
||||
|
||||
float DirectoryIterator::getEstimatedProgress() const
|
||||
{
|
||||
if (totalNumFiles < 0)
|
||||
totalNumFiles = File (path).getNumberOfChildFiles (File::findFilesAndDirectories);
|
||||
|
||||
if (totalNumFiles <= 0)
|
||||
return 0.0f;
|
||||
|
||||
const float detailedIndex = (subIterator != nullptr) ? index + subIterator->getEstimatedProgress()
|
||||
: (float) index;
|
||||
|
||||
return detailedIndex / totalNumFiles;
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -1,157 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_FILES_DIRECTORYITERATOR_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_FILES_DIRECTORYITERATOR_H_INCLUDED
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Searches through a the files in a directory, returning each file that is found.
|
||||
|
||||
A DirectoryIterator will search through a directory and its subdirectories using
|
||||
a wildcard filepattern match.
|
||||
|
||||
If you may be finding a large number of files, this is better than
|
||||
using File::findChildFiles() because it doesn't block while it finds them
|
||||
all, and this is more memory-efficient.
|
||||
|
||||
It can also guess how far it's got using a wildly inaccurate algorithm.
|
||||
*/
|
||||
class DirectoryIterator
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a DirectoryIterator for a given directory.
|
||||
|
||||
After creating one of these, call its next() method to get the
|
||||
first file - e.g. @code
|
||||
|
||||
DirectoryIterator iter (File ("/animals/mooses"), true, "*.moose");
|
||||
|
||||
while (iter.next())
|
||||
{
|
||||
File theFileItFound (iter.getFile());
|
||||
|
||||
... etc
|
||||
}
|
||||
@endcode
|
||||
|
||||
@param directory the directory to search in
|
||||
@param isRecursive whether all the subdirectories should also be searched
|
||||
@param wildCard the file pattern to match. This may contain multiple patterns
|
||||
separated by a semi-colon or comma, e.g. "*.jpg;*.png"
|
||||
@param whatToLookFor a value from the File::TypesOfFileToFind enum, specifying
|
||||
whether to look for files, directories, or both.
|
||||
*/
|
||||
DirectoryIterator (const File& directory,
|
||||
bool isRecursive,
|
||||
const String& wildCard = "*",
|
||||
int whatToLookFor = File::findFiles);
|
||||
|
||||
DirectoryIterator(DirectoryIterator const&) = delete;
|
||||
DirectoryIterator& operator= (DirectoryIterator const&) = delete;
|
||||
|
||||
/** Destructor. */
|
||||
~DirectoryIterator();
|
||||
|
||||
/** Moves the iterator along to the next file.
|
||||
|
||||
@returns true if a file was found (you can then use getFile() to see what it was) - or
|
||||
false if there are no more matching files.
|
||||
*/
|
||||
bool next();
|
||||
|
||||
/** Moves the iterator along to the next file, and returns various properties of that file.
|
||||
|
||||
If you need to find out details about the file, it's more efficient to call this method than
|
||||
to call the normal next() method and then find out the details afterwards.
|
||||
|
||||
All the parameters are optional, so pass null pointers for any items that you're not
|
||||
interested in.
|
||||
|
||||
@returns true if a file was found (you can then use getFile() to see what it was) - or
|
||||
false if there are no more matching files. If it returns false, then none of the
|
||||
parameters will be filled-in.
|
||||
*/
|
||||
bool next (bool* isDirectory,
|
||||
bool* isHidden,
|
||||
std::int64_t* fileSize,
|
||||
Time* modTime,
|
||||
Time* creationTime,
|
||||
bool* isReadOnly);
|
||||
|
||||
/** Returns the file that the iterator is currently pointing at.
|
||||
|
||||
The result of this call is only valid after a call to next() has returned true.
|
||||
*/
|
||||
const File& getFile() const;
|
||||
|
||||
/** Returns a guess of how far through the search the iterator has got.
|
||||
|
||||
@returns a value 0.0 to 1.0 to show the progress, although this won't be
|
||||
very accurate.
|
||||
*/
|
||||
float getEstimatedProgress() const;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class NativeIterator
|
||||
{
|
||||
public:
|
||||
NativeIterator (const File& directory, const String& wildCard);
|
||||
|
||||
NativeIterator(NativeIterator const&) = delete;
|
||||
NativeIterator& operator= (NativeIterator const&) = delete;
|
||||
|
||||
~NativeIterator();
|
||||
|
||||
bool next (String& filenameFound,
|
||||
bool* isDirectory, bool* isHidden, std::int64_t* fileSize,
|
||||
Time* modTime, Time* creationTime, bool* isReadOnly);
|
||||
|
||||
class Pimpl;
|
||||
|
||||
private:
|
||||
friend class DirectoryIterator;
|
||||
std::unique_ptr<Pimpl> pimpl;
|
||||
};
|
||||
|
||||
StringArray wildCards;
|
||||
NativeIterator fileFinder;
|
||||
String wildCard, path;
|
||||
int index;
|
||||
mutable int totalNumFiles;
|
||||
const int whatToLookFor;
|
||||
const bool isRecursive;
|
||||
bool hasBeenAdvanced;
|
||||
std::unique_ptr <DirectoryIterator> subIterator;
|
||||
File currentFile;
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_DIRECTORYITERATOR_H_INCLUDED
|
||||
@@ -1,531 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
|
||||
namespace beast {
|
||||
|
||||
File const& File::nonexistent()
|
||||
{
|
||||
static File const instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
File::File (const String& fullPathName)
|
||||
: fullPath (parseAbsolutePath (fullPathName))
|
||||
{
|
||||
}
|
||||
|
||||
File::File (const File& other)
|
||||
: fullPath (other.fullPath)
|
||||
{
|
||||
}
|
||||
|
||||
File File::createFileWithoutCheckingPath (const String& path) noexcept
|
||||
{
|
||||
File f;
|
||||
f.fullPath = path;
|
||||
return f;
|
||||
}
|
||||
|
||||
File& File::operator= (const String& newPath)
|
||||
{
|
||||
fullPath = parseAbsolutePath (newPath);
|
||||
return *this;
|
||||
}
|
||||
|
||||
File& File::operator= (const File& other)
|
||||
{
|
||||
fullPath = other.fullPath;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
File::File (File&& other) noexcept
|
||||
: fullPath (static_cast <String&&> (other.fullPath))
|
||||
{
|
||||
}
|
||||
|
||||
File& File::operator= (File&& other) noexcept
|
||||
{
|
||||
fullPath = static_cast <String&&> (other.fullPath);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
String File::parseAbsolutePath (const String& p)
|
||||
{
|
||||
if (p.isEmpty())
|
||||
return String::empty;
|
||||
|
||||
#if BEAST_WINDOWS
|
||||
// Windows..
|
||||
String path (p.replaceCharacter ('/', '\\'));
|
||||
|
||||
if (path.startsWithChar (separator))
|
||||
{
|
||||
if (path[1] != separator)
|
||||
{
|
||||
/* When you supply a raw string to the File object constructor, it must be an absolute path.
|
||||
If you're trying to parse a string that may be either a relative path or an absolute path,
|
||||
you MUST provide a context against which the partial path can be evaluated - you can do
|
||||
this by simply using File::getChildFile() instead of the File constructor. E.g. saying
|
||||
"File::getCurrentWorkingDirectory().getChildFile (myUnknownPath)" would return an absolute
|
||||
path if that's what was supplied, or would evaluate a partial path relative to the CWD.
|
||||
*/
|
||||
bassertfalse;
|
||||
|
||||
path = File::getCurrentWorkingDirectory().getFullPathName().substring (0, 2) + path;
|
||||
}
|
||||
}
|
||||
else if (! path.containsChar (':'))
|
||||
{
|
||||
/* When you supply a raw string to the File object constructor, it must be an absolute path.
|
||||
If you're trying to parse a string that may be either a relative path or an absolute path,
|
||||
you MUST provide a context against which the partial path can be evaluated - you can do
|
||||
this by simply using File::getChildFile() instead of the File constructor. E.g. saying
|
||||
"File::getCurrentWorkingDirectory().getChildFile (myUnknownPath)" would return an absolute
|
||||
path if that's what was supplied, or would evaluate a partial path relative to the CWD.
|
||||
*/
|
||||
bassertfalse;
|
||||
|
||||
return File::getCurrentWorkingDirectory().getChildFile (path).getFullPathName();
|
||||
}
|
||||
#else
|
||||
// Mac or Linux..
|
||||
|
||||
// Yes, I know it's legal for a unix pathname to contain a backslash, but this assertion is here
|
||||
// to catch anyone who's trying to run code that was written on Windows with hard-coded path names.
|
||||
// If that's why you've ended up here, use File::getChildFile() to build your paths instead.
|
||||
bassert ((! p.containsChar ('\\')) || (p.indexOfChar ('/') >= 0 && p.indexOfChar ('/') < p.indexOfChar ('\\')));
|
||||
|
||||
String path (p);
|
||||
|
||||
if (path.startsWithChar ('~'))
|
||||
{
|
||||
if (path[1] == separator || path[1] == 0)
|
||||
{
|
||||
// expand a name of the form "~/abc"
|
||||
path = File::getSpecialLocation (File::userHomeDirectory).getFullPathName()
|
||||
+ path.substring (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// expand a name of type "~dave/abc"
|
||||
const String userName (path.substring (1).upToFirstOccurrenceOf ("/", false, false));
|
||||
|
||||
if (struct passwd* const pw = getpwnam (userName.toUTF8()))
|
||||
path = addTrailingSeparator (pw->pw_dir) + path.fromFirstOccurrenceOf ("/", false, false);
|
||||
}
|
||||
}
|
||||
else if (! path.startsWithChar (separator))
|
||||
{
|
||||
#if BEAST_DEBUG || BEAST_LOG_ASSERTIONS
|
||||
if (! (path.startsWith ("./") || path.startsWith ("../")))
|
||||
{
|
||||
/* When you supply a raw string to the File object constructor, it must be an absolute path.
|
||||
If you're trying to parse a string that may be either a relative path or an absolute path,
|
||||
you MUST provide a context against which the partial path can be evaluated - you can do
|
||||
this by simply using File::getChildFile() instead of the File constructor. E.g. saying
|
||||
"File::getCurrentWorkingDirectory().getChildFile (myUnknownPath)" would return an absolute
|
||||
path if that's what was supplied, or would evaluate a partial path relative to the CWD.
|
||||
*/
|
||||
bassertfalse;
|
||||
}
|
||||
#endif
|
||||
|
||||
return File::getCurrentWorkingDirectory().getChildFile (path).getFullPathName();
|
||||
}
|
||||
#endif
|
||||
|
||||
while (path.endsWithChar (separator) && path != separatorString) // careful not to turn a single "/" into an empty string.
|
||||
path = path.dropLastCharacters (1);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
String File::addTrailingSeparator (const String& path)
|
||||
{
|
||||
return path.endsWithChar (separator) ? path
|
||||
: path + separator;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if BEAST_LINUX
|
||||
#define NAMES_ARE_CASE_SENSITIVE 1
|
||||
#endif
|
||||
|
||||
bool File::areFileNamesCaseSensitive()
|
||||
{
|
||||
#if NAMES_ARE_CASE_SENSITIVE
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int compareFilenames (const String& name1, const String& name2) noexcept
|
||||
{
|
||||
#if NAMES_ARE_CASE_SENSITIVE
|
||||
return name1.compare (name2);
|
||||
#else
|
||||
return name1.compareIgnoreCase (name2);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool File::operator== (const File& other) const { return compareFilenames (fullPath, other.fullPath) == 0; }
|
||||
bool File::operator!= (const File& other) const { return compareFilenames (fullPath, other.fullPath) != 0; }
|
||||
bool File::operator< (const File& other) const { return compareFilenames (fullPath, other.fullPath) < 0; }
|
||||
bool File::operator> (const File& other) const { return compareFilenames (fullPath, other.fullPath) > 0; }
|
||||
|
||||
//==============================================================================
|
||||
bool File::deleteRecursively() const
|
||||
{
|
||||
bool worked = true;
|
||||
|
||||
if (isDirectory())
|
||||
{
|
||||
Array<File> subFiles;
|
||||
findChildFiles (subFiles, File::findFilesAndDirectories, false);
|
||||
|
||||
for (int i = subFiles.size(); --i >= 0;)
|
||||
worked = subFiles.getReference(i).deleteRecursively() && worked;
|
||||
}
|
||||
|
||||
return deleteFile() && worked;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
String File::getPathUpToLastSlash() const
|
||||
{
|
||||
const int lastSlash = fullPath.lastIndexOfChar (separator);
|
||||
|
||||
if (lastSlash > 0)
|
||||
return fullPath.substring (0, lastSlash);
|
||||
|
||||
if (lastSlash == 0)
|
||||
return separatorString;
|
||||
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
File File::getParentDirectory() const
|
||||
{
|
||||
File f;
|
||||
f.fullPath = getPathUpToLastSlash();
|
||||
return f;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
String File::getFileName() const
|
||||
{
|
||||
return fullPath.substring (fullPath.lastIndexOfChar (separator) + 1);
|
||||
}
|
||||
|
||||
String File::getFileNameWithoutExtension() const
|
||||
{
|
||||
const int lastSlash = fullPath.lastIndexOfChar (separator) + 1;
|
||||
const int lastDot = fullPath.lastIndexOfChar ('.');
|
||||
|
||||
if (lastDot > lastSlash)
|
||||
return fullPath.substring (lastSlash, lastDot);
|
||||
|
||||
return fullPath.substring (lastSlash);
|
||||
}
|
||||
|
||||
bool File::isAChildOf (const File& potentialParent) const
|
||||
{
|
||||
if (potentialParent == File::nonexistent ())
|
||||
return false;
|
||||
|
||||
const String ourPath (getPathUpToLastSlash());
|
||||
|
||||
if (compareFilenames (potentialParent.fullPath, ourPath) == 0)
|
||||
return true;
|
||||
|
||||
if (potentialParent.fullPath.length() >= ourPath.length())
|
||||
return false;
|
||||
|
||||
return getParentDirectory().isAChildOf (potentialParent);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool File::isAbsolutePath (const String& path)
|
||||
{
|
||||
return path.startsWithChar (separator)
|
||||
#if BEAST_WINDOWS
|
||||
|| (path.isNotEmpty() && path[1] == ':');
|
||||
#else
|
||||
|| path.startsWithChar ('~');
|
||||
#endif
|
||||
}
|
||||
|
||||
File File::getChildFile (String relativePath) const
|
||||
{
|
||||
if (isAbsolutePath (relativePath))
|
||||
return File (relativePath);
|
||||
|
||||
String path (fullPath);
|
||||
|
||||
// It's relative, so remove any ../ or ./ bits at the start..
|
||||
if (relativePath[0] == '.')
|
||||
{
|
||||
#if BEAST_WINDOWS
|
||||
relativePath = relativePath.replaceCharacter ('/', '\\');
|
||||
#endif
|
||||
|
||||
while (relativePath[0] == '.')
|
||||
{
|
||||
const beast_wchar secondChar = relativePath[1];
|
||||
|
||||
if (secondChar == '.')
|
||||
{
|
||||
const beast_wchar thirdChar = relativePath[2];
|
||||
|
||||
if (thirdChar == 0 || thirdChar == separator)
|
||||
{
|
||||
const int lastSlash = path.lastIndexOfChar (separator);
|
||||
if (lastSlash >= 0)
|
||||
path = path.substring (0, lastSlash);
|
||||
|
||||
relativePath = relativePath.substring (3);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (secondChar == separator)
|
||||
{
|
||||
relativePath = relativePath.substring (2);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return File (addTrailingSeparator (path) + relativePath);
|
||||
}
|
||||
|
||||
File File::getSiblingFile (const String& fileName) const
|
||||
{
|
||||
return getParentDirectory().getChildFile (fileName);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
Result File::create() const
|
||||
{
|
||||
if (exists())
|
||||
return Result::ok();
|
||||
|
||||
const File parentDir (getParentDirectory());
|
||||
|
||||
if (parentDir == *this)
|
||||
return Result::fail ("Cannot create parent directory");
|
||||
|
||||
Result r (parentDir.createDirectory());
|
||||
|
||||
if (r.wasOk())
|
||||
{
|
||||
FileOutputStream fo (*this, 8);
|
||||
r = fo.getStatus();
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
Result File::createDirectory() const
|
||||
{
|
||||
if (isDirectory())
|
||||
return Result::ok();
|
||||
|
||||
const File parentDir (getParentDirectory());
|
||||
|
||||
if (parentDir == *this)
|
||||
return Result::fail ("Cannot create parent directory");
|
||||
|
||||
Result r (parentDir.createDirectory());
|
||||
|
||||
if (r.wasOk())
|
||||
r = createDirectoryInternal (fullPath.trimCharactersAtEnd (separatorString));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int File::findChildFiles (Array<File>& results,
|
||||
const int whatToLookFor,
|
||||
const bool searchRecursively,
|
||||
const String& wildCardPattern) const
|
||||
{
|
||||
DirectoryIterator di (*this, searchRecursively, wildCardPattern, whatToLookFor);
|
||||
|
||||
int total = 0;
|
||||
while (di.next())
|
||||
{
|
||||
results.add (di.getFile());
|
||||
++total;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int File::getNumberOfChildFiles (const int whatToLookFor, const String& wildCardPattern) const
|
||||
{
|
||||
DirectoryIterator di (*this, false, wildCardPattern, whatToLookFor);
|
||||
|
||||
int total = 0;
|
||||
while (di.next())
|
||||
++total;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
String File::getFileExtension() const
|
||||
{
|
||||
const int indexOfDot = fullPath.lastIndexOfChar ('.');
|
||||
|
||||
if (indexOfDot > fullPath.lastIndexOfChar (separator))
|
||||
return fullPath.substring (indexOfDot);
|
||||
|
||||
return String::empty;
|
||||
}
|
||||
|
||||
bool File::hasFileExtension (const String& possibleSuffix) const
|
||||
{
|
||||
if (possibleSuffix.isEmpty())
|
||||
return fullPath.lastIndexOfChar ('.') <= fullPath.lastIndexOfChar (separator);
|
||||
|
||||
const int semicolon = possibleSuffix.indexOfChar (0, ';');
|
||||
|
||||
if (semicolon >= 0)
|
||||
{
|
||||
return hasFileExtension (possibleSuffix.substring (0, semicolon).trimEnd())
|
||||
|| hasFileExtension (possibleSuffix.substring (semicolon + 1).trimStart());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fullPath.endsWithIgnoreCase (possibleSuffix))
|
||||
{
|
||||
if (possibleSuffix.startsWithChar ('.'))
|
||||
return true;
|
||||
|
||||
const int dotPos = fullPath.length() - possibleSuffix.length() - 1;
|
||||
|
||||
if (dotPos >= 0)
|
||||
return fullPath [dotPos] == '.';
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
File File::withFileExtension (const String& newExtension) const
|
||||
{
|
||||
if (fullPath.isEmpty())
|
||||
return File::nonexistent ();
|
||||
|
||||
String filePart (getFileName());
|
||||
|
||||
const int i = filePart.lastIndexOfChar ('.');
|
||||
if (i >= 0)
|
||||
filePart = filePart.substring (0, i);
|
||||
|
||||
if (newExtension.isNotEmpty() && ! newExtension.startsWithChar ('.'))
|
||||
filePart << '.';
|
||||
|
||||
return getSiblingFile (filePart + newExtension);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
FileInputStream* File::createInputStream() const
|
||||
{
|
||||
std::unique_ptr <FileInputStream> fin (new FileInputStream (*this));
|
||||
|
||||
if (fin->openedOk())
|
||||
return fin.release();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FileOutputStream* File::createOutputStream (const size_t bufferSize) const
|
||||
{
|
||||
std::unique_ptr <FileOutputStream> out (new FileOutputStream (*this, bufferSize));
|
||||
|
||||
return out->failedToOpen() ? nullptr
|
||||
: out.release();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool File::appendData (const void* const dataToAppend,
|
||||
const size_t numberOfBytes) const
|
||||
{
|
||||
bassert (((std::ptrdiff_t) numberOfBytes) >= 0);
|
||||
|
||||
if (numberOfBytes == 0)
|
||||
return true;
|
||||
|
||||
FileOutputStream out (*this, 8192);
|
||||
return out.openedOk() && out.write (dataToAppend, numberOfBytes);
|
||||
}
|
||||
|
||||
bool File::appendText (const String& text,
|
||||
const bool asUnicode,
|
||||
const bool writeUnicodeHeaderBytes) const
|
||||
{
|
||||
FileOutputStream out (*this);
|
||||
|
||||
if (out.failedToOpen())
|
||||
return false;
|
||||
|
||||
out.writeText (text, asUnicode, writeUnicodeHeaderBytes);
|
||||
return true;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
File File::createTempFile (const String& fileNameEnding)
|
||||
{
|
||||
auto const tempDir = getSpecialLocation (tempDirectory);
|
||||
std::random_device rng;
|
||||
File tempFile;
|
||||
|
||||
do
|
||||
{
|
||||
tempFile = tempDir.getChildFile (
|
||||
"temp_" + std::to_string(rng()))
|
||||
.withFileExtension (fileNameEnding);
|
||||
}
|
||||
while (tempFile.exists());
|
||||
|
||||
return tempFile;
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -1,529 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_FILES_FILE_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_FILES_FILE_H_INCLUDED
|
||||
|
||||
#include <beast/module/core/containers/Array.h>
|
||||
#include <beast/module/core/memory/MemoryBlock.h>
|
||||
#include <beast/module/core/misc/Result.h>
|
||||
#include <beast/module/core/text/StringArray.h>
|
||||
#include <beast/module/core/threads/CriticalSection.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class FileInputStream;
|
||||
class FileOutputStream;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Represents a local file or directory.
|
||||
|
||||
This class encapsulates the absolute pathname of a file or directory, and
|
||||
has methods for finding out about the file and changing its properties.
|
||||
|
||||
To read or write to the file, there are methods for returning an input or
|
||||
output stream.
|
||||
|
||||
@see FileInputStream, FileOutputStream
|
||||
*/
|
||||
class File
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an (invalid) file object.
|
||||
|
||||
The file is initially set to an empty path, so getFullPath() will return
|
||||
an empty string, and comparing the file to File::nonexistent will return
|
||||
true.
|
||||
|
||||
You can use its operator= method to point it at a proper file.
|
||||
*/
|
||||
File() noexcept {}
|
||||
|
||||
/** Creates a file from an absolute path.
|
||||
|
||||
If the path supplied is a relative path, it is taken to be relative
|
||||
to the current working directory (see File::getCurrentWorkingDirectory()),
|
||||
but this isn't a recommended way of creating a file, because you
|
||||
never know what the CWD is going to be.
|
||||
|
||||
On the Mac/Linux, the path can include "~" notation for referring to
|
||||
user home directories.
|
||||
*/
|
||||
File (const String& absolutePath);
|
||||
|
||||
/** Creates a copy of another file object. */
|
||||
File (const File&);
|
||||
|
||||
/** Destructor. */
|
||||
~File() noexcept {}
|
||||
|
||||
/** Sets the file based on an absolute pathname.
|
||||
|
||||
If the path supplied is a relative path, it is taken to be relative
|
||||
to the current working directory (see File::getCurrentWorkingDirectory()),
|
||||
but this isn't a recommended way of creating a file, because you
|
||||
never know what the CWD is going to be.
|
||||
|
||||
On the Mac/Linux, the path can include "~" notation for referring to
|
||||
user home directories.
|
||||
*/
|
||||
File& operator= (const String& newAbsolutePath);
|
||||
|
||||
/** Copies from another file object. */
|
||||
File& operator= (const File& otherFile);
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
File (File&&) noexcept;
|
||||
File& operator= (File&&) noexcept;
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
/** This static constant is used for referring to an 'invalid' file. */
|
||||
static File const& nonexistent ();
|
||||
|
||||
//==============================================================================
|
||||
/** Checks whether the file actually exists.
|
||||
|
||||
@returns true if the file exists, either as a file or a directory.
|
||||
@see existsAsFile, isDirectory
|
||||
*/
|
||||
bool exists() const;
|
||||
|
||||
/** Checks whether the file exists and is a file rather than a directory.
|
||||
|
||||
@returns true only if this is a real file, false if it's a directory
|
||||
or doesn't exist
|
||||
@see exists, isDirectory
|
||||
*/
|
||||
bool existsAsFile() const;
|
||||
|
||||
/** Checks whether the file is a directory that exists.
|
||||
|
||||
@returns true only if the file is a directory which actually exists, so
|
||||
false if it's a file or doesn't exist at all
|
||||
@see exists, existsAsFile
|
||||
*/
|
||||
bool isDirectory() const;
|
||||
|
||||
/** Returns the size of the file in bytes.
|
||||
|
||||
@returns the number of bytes in the file, or 0 if it doesn't exist.
|
||||
*/
|
||||
std::int64_t getSize() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the complete, absolute path of this file.
|
||||
|
||||
This includes the filename and all its parent folders. On Windows it'll
|
||||
also include the drive letter prefix; on Mac or Linux it'll be a complete
|
||||
path starting from the root folder.
|
||||
|
||||
If you just want the file's name, you should use getFileName() or
|
||||
getFileNameWithoutExtension().
|
||||
|
||||
@see getFileName
|
||||
*/
|
||||
const String& getFullPathName() const noexcept { return fullPath; }
|
||||
|
||||
/** Returns the last section of the pathname.
|
||||
|
||||
Returns just the final part of the path - e.g. if the whole path
|
||||
is "/moose/fish/foo.txt" this will return "foo.txt".
|
||||
|
||||
For a directory, it returns the final part of the path - e.g. for the
|
||||
directory "/moose/fish" it'll return "fish".
|
||||
|
||||
If the filename begins with a dot, it'll return the whole filename, e.g. for
|
||||
"/moose/.fish", it'll return ".fish"
|
||||
|
||||
@see getFullPathName, getFileNameWithoutExtension
|
||||
*/
|
||||
String getFileName() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the file's extension.
|
||||
|
||||
Returns the file extension of this file, also including the dot.
|
||||
|
||||
e.g. "/moose/fish/foo.txt" would return ".txt"
|
||||
|
||||
@see hasFileExtension, withFileExtension, getFileNameWithoutExtension
|
||||
*/
|
||||
String getFileExtension() const;
|
||||
|
||||
/** Checks whether the file has a given extension.
|
||||
|
||||
@param extensionToTest the extension to look for - it doesn't matter whether or
|
||||
not this string has a dot at the start, so ".wav" and "wav"
|
||||
will have the same effect. To compare with multiple extensions, this
|
||||
parameter can contain multiple strings, separated by semi-colons -
|
||||
so, for example: hasFileExtension (".jpeg;png;gif") would return
|
||||
true if the file has any of those three extensions.
|
||||
|
||||
@see getFileExtension, withFileExtension, getFileNameWithoutExtension
|
||||
*/
|
||||
bool hasFileExtension (const String& extensionToTest) const;
|
||||
|
||||
/** Returns a version of this file with a different file extension.
|
||||
|
||||
e.g. File ("/moose/fish/foo.txt").withFileExtension ("html") returns "/moose/fish/foo.html"
|
||||
|
||||
@param newExtension the new extension, either with or without a dot at the start (this
|
||||
doesn't make any difference). To get remove a file's extension altogether,
|
||||
pass an empty string into this function.
|
||||
|
||||
@see getFileName, getFileExtension, hasFileExtension, getFileNameWithoutExtension
|
||||
*/
|
||||
File withFileExtension (const String& newExtension) const;
|
||||
|
||||
/** Returns the last part of the filename, without its file extension.
|
||||
|
||||
e.g. for "/moose/fish/foo.txt" this will return "foo".
|
||||
|
||||
@see getFileName, getFileExtension, hasFileExtension, withFileExtension
|
||||
*/
|
||||
String getFileNameWithoutExtension() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a file that represents a relative (or absolute) sub-path of the current one.
|
||||
|
||||
This will find a child file or directory of the current object.
|
||||
|
||||
e.g.
|
||||
File ("/moose/fish").getChildFile ("foo.txt") will produce "/moose/fish/foo.txt".
|
||||
File ("/moose/fish").getChildFile ("haddock/foo.txt") will produce "/moose/fish/haddock/foo.txt".
|
||||
File ("/moose/fish").getChildFile ("../foo.txt") will produce "/moose/foo.txt".
|
||||
|
||||
If the string is actually an absolute path, it will be treated as such, e.g.
|
||||
File ("/moose/fish").getChildFile ("/foo.txt") will produce "/foo.txt"
|
||||
|
||||
@see getSiblingFile, getParentDirectory, isAChildOf
|
||||
*/
|
||||
File getChildFile (String relativeOrAbsolutePath) const;
|
||||
|
||||
/** Returns a file which is in the same directory as this one.
|
||||
|
||||
This is equivalent to getParentDirectory().getChildFile (name).
|
||||
|
||||
@see getChildFile, getParentDirectory
|
||||
*/
|
||||
File getSiblingFile (const String& siblingFileName) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the directory that contains this file or directory.
|
||||
|
||||
e.g. for "/moose/fish/foo.txt" this will return "/moose/fish".
|
||||
*/
|
||||
File getParentDirectory() const;
|
||||
|
||||
/** Checks whether a file is somewhere inside a directory.
|
||||
|
||||
Returns true if this file is somewhere inside a subdirectory of the directory
|
||||
that is passed in. Neither file actually has to exist, because the function
|
||||
just checks the paths for similarities.
|
||||
|
||||
e.g. File ("/moose/fish/foo.txt").isAChildOf ("/moose") is true.
|
||||
File ("/moose/fish/foo.txt").isAChildOf ("/moose/fish") is also true.
|
||||
*/
|
||||
bool isAChildOf (const File& potentialParentDirectory) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Compares the pathnames for two files. */
|
||||
bool operator== (const File&) const;
|
||||
/** Compares the pathnames for two files. */
|
||||
bool operator!= (const File&) const;
|
||||
/** Compares the pathnames for two files. */
|
||||
bool operator< (const File&) const;
|
||||
/** Compares the pathnames for two files. */
|
||||
bool operator> (const File&) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Creates an empty file if it doesn't already exist.
|
||||
|
||||
If the file that this object refers to doesn't exist, this will create a file
|
||||
of zero size.
|
||||
|
||||
If it already exists or is a directory, this method will do nothing.
|
||||
|
||||
@returns true if the file has been created (or if it already existed).
|
||||
@see createDirectory
|
||||
*/
|
||||
Result create() const;
|
||||
|
||||
/** Creates a new directory for this filename.
|
||||
|
||||
This will try to create the file as a directory, and fill also create
|
||||
any parent directories it needs in order to complete the operation.
|
||||
|
||||
@returns a result to indicate whether the directory was created successfully, or
|
||||
an error message if it failed.
|
||||
@see create
|
||||
*/
|
||||
Result createDirectory() const;
|
||||
|
||||
/** Deletes a file.
|
||||
|
||||
If this file is actually a directory, it may not be deleted correctly if it
|
||||
contains files. See deleteRecursively() as a better way of deleting directories.
|
||||
|
||||
@returns true if the file has been successfully deleted (or if it didn't exist to
|
||||
begin with).
|
||||
@see deleteRecursively
|
||||
*/
|
||||
bool deleteFile() const;
|
||||
|
||||
/** Deletes a file or directory and all its subdirectories.
|
||||
|
||||
If this file is a directory, this will try to delete it and all its subfolders. If
|
||||
it's just a file, it will just try to delete the file.
|
||||
|
||||
@returns true if the file and all its subfolders have been successfully deleted
|
||||
(or if it didn't exist to begin with).
|
||||
@see deleteFile
|
||||
*/
|
||||
bool deleteRecursively() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Used in file searching, to specify whether to return files, directories, or both.
|
||||
*/
|
||||
enum TypesOfFileToFind
|
||||
{
|
||||
findDirectories = 1, /**< Use this flag to indicate that you want to find directories. */
|
||||
findFiles = 2, /**< Use this flag to indicate that you want to find files. */
|
||||
findFilesAndDirectories = 3, /**< Use this flag to indicate that you want to find both files and directories. */
|
||||
ignoreHiddenFiles = 4 /**< Add this flag to avoid returning any hidden files in the results. */
|
||||
};
|
||||
|
||||
/** Searches inside a directory for files matching a wildcard pattern.
|
||||
|
||||
Assuming that this file is a directory, this method will search it
|
||||
for either files or subdirectories whose names match a filename pattern.
|
||||
|
||||
@param results an array to which File objects will be added for the
|
||||
files that the search comes up with
|
||||
@param whatToLookFor a value from the TypesOfFileToFind enum, specifying whether to
|
||||
return files, directories, or both. If the ignoreHiddenFiles flag
|
||||
is also added to this value, hidden files won't be returned
|
||||
@param searchRecursively if true, all subdirectories will be recursed into to do
|
||||
an exhaustive search
|
||||
@param wildCardPattern the filename pattern to search for, e.g. "*.txt"
|
||||
@returns the number of results that have been found
|
||||
|
||||
@see getNumberOfChildFiles, DirectoryIterator
|
||||
*/
|
||||
int findChildFiles (Array<File>& results,
|
||||
int whatToLookFor,
|
||||
bool searchRecursively,
|
||||
const String& wildCardPattern = "*") const;
|
||||
|
||||
/** Searches inside a directory and counts how many files match a wildcard pattern.
|
||||
|
||||
Assuming that this file is a directory, this method will search it
|
||||
for either files or subdirectories whose names match a filename pattern,
|
||||
and will return the number of matches found.
|
||||
|
||||
This isn't a recursive call, and will only search this directory, not
|
||||
its children.
|
||||
|
||||
@param whatToLookFor a value from the TypesOfFileToFind enum, specifying whether to
|
||||
count files, directories, or both. If the ignoreHiddenFiles flag
|
||||
is also added to this value, hidden files won't be counted
|
||||
@param wildCardPattern the filename pattern to search for, e.g. "*.txt"
|
||||
@returns the number of matches found
|
||||
@see findChildFiles, DirectoryIterator
|
||||
*/
|
||||
int getNumberOfChildFiles (int whatToLookFor,
|
||||
const String& wildCardPattern = "*") const;
|
||||
|
||||
//==============================================================================
|
||||
/** Creates a stream to read from this file.
|
||||
|
||||
@returns a stream that will read from this file (initially positioned at the
|
||||
start of the file), or nullptr if the file can't be opened for some reason
|
||||
@see createOutputStream
|
||||
*/
|
||||
FileInputStream* createInputStream() const;
|
||||
|
||||
/** Creates a stream to write to this file.
|
||||
|
||||
If the file exists, the stream that is returned will be positioned ready for
|
||||
writing at the end of the file, so you might want to use deleteFile() first
|
||||
to write to an empty file.
|
||||
|
||||
@returns a stream that will write to this file (initially positioned at the
|
||||
end of the file), or nullptr if the file can't be opened for some reason
|
||||
@see createInputStream, appendData, appendText
|
||||
*/
|
||||
FileOutputStream* createOutputStream (size_t bufferSize = 0x8000) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Appends a block of binary data to the end of the file.
|
||||
|
||||
This will try to write the given buffer to the end of the file.
|
||||
|
||||
@returns false if it can't write to the file for some reason
|
||||
*/
|
||||
bool appendData (const void* dataToAppend,
|
||||
size_t numberOfBytes) const;
|
||||
|
||||
/** Appends a string to the end of the file.
|
||||
|
||||
This will try to append a text string to the file, as either 16-bit unicode
|
||||
or 8-bit characters in the default system encoding.
|
||||
|
||||
It can also write the 'ff fe' unicode header bytes before the text to indicate
|
||||
the endianness of the file.
|
||||
|
||||
Any single \\n characters in the string are replaced with \\r\\n before it is written.
|
||||
|
||||
@see replaceWithText
|
||||
*/
|
||||
bool appendText (const String& textToAppend,
|
||||
bool asUnicode = false,
|
||||
bool writeUnicodeHeaderBytes = false) const;
|
||||
|
||||
//==============================================================================
|
||||
/** A set of types of location that can be passed to the getSpecialLocation() method.
|
||||
*/
|
||||
enum SpecialLocationType
|
||||
{
|
||||
/** The user's home folder. This is the same as using File ("~"). */
|
||||
userHomeDirectory,
|
||||
|
||||
/** The user's default documents folder. On Windows, this might be the user's
|
||||
"My Documents" folder. On the Mac it'll be their "Documents" folder. Linux
|
||||
doesn't tend to have one of these, so it might just return their home folder.
|
||||
*/
|
||||
userDocumentsDirectory,
|
||||
|
||||
/** The folder that contains the user's desktop objects. */
|
||||
userDesktopDirectory,
|
||||
|
||||
/** The most likely place where a user might store their music files. */
|
||||
userMusicDirectory,
|
||||
|
||||
/** The most likely place where a user might store their movie files. */
|
||||
userMoviesDirectory,
|
||||
|
||||
/** The most likely place where a user might store their picture files. */
|
||||
userPicturesDirectory,
|
||||
|
||||
/** The folder in which applications store their persistent user-specific settings.
|
||||
On Windows, this might be "\Documents and Settings\username\Application Data".
|
||||
On the Mac, it might be "~/Library". If you're going to store your settings in here,
|
||||
always create your own sub-folder to put them in, to avoid making a mess.
|
||||
*/
|
||||
userApplicationDataDirectory,
|
||||
|
||||
/** An equivalent of the userApplicationDataDirectory folder that is shared by all users
|
||||
of the computer, rather than just the current user.
|
||||
|
||||
On the Mac it'll be "/Library", on Windows, it could be something like
|
||||
"\Documents and Settings\All Users\Application Data".
|
||||
|
||||
Depending on the setup, this folder may be read-only.
|
||||
*/
|
||||
commonApplicationDataDirectory,
|
||||
|
||||
/** A place to put documents which are shared by all users of the machine.
|
||||
On Windows this may be somewhere like "C:\Users\Public\Documents", on OSX it
|
||||
will be something like "/Users/Shared". Other OSes may have no such concept
|
||||
though, so be careful.
|
||||
*/
|
||||
commonDocumentsDirectory,
|
||||
|
||||
/** The folder that should be used for temporary files.
|
||||
Always delete them when you're finished, to keep the user's computer tidy!
|
||||
*/
|
||||
tempDirectory,
|
||||
|
||||
/** The directory in which applications normally get installed.
|
||||
So on windows, this would be something like "c:\program files", on the
|
||||
Mac "/Applications", or "/usr" on linux.
|
||||
*/
|
||||
globalApplicationsDirectory
|
||||
};
|
||||
|
||||
/** Finds the location of a special type of file or directory, such as a home folder or
|
||||
documents folder.
|
||||
|
||||
@see SpecialLocationType
|
||||
*/
|
||||
static File getSpecialLocation (const SpecialLocationType type);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a temporary file in the system's temp directory.
|
||||
This will try to return the name of a non-existent temp file.
|
||||
To get the temp folder, you can use getSpecialLocation (File::tempDirectory).
|
||||
*/
|
||||
static File createTempFile (const String& fileNameEnding);
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the current working directory. */
|
||||
static File getCurrentWorkingDirectory();
|
||||
|
||||
//==============================================================================
|
||||
/** The system-specific file separator character.
|
||||
On Windows, this will be '\', on Mac/Linux, it'll be '/'
|
||||
*/
|
||||
static const beast_wchar separator;
|
||||
|
||||
/** The system-specific file separator character, as a string.
|
||||
On Windows, this will be '\', on Mac/Linux, it'll be '/'
|
||||
*/
|
||||
static const String separatorString;
|
||||
|
||||
//==============================================================================
|
||||
/** Indicates whether filenames are case-sensitive on the current operating system. */
|
||||
static bool areFileNamesCaseSensitive();
|
||||
|
||||
/** Returns true if the string seems to be a fully-specified absolute path. */
|
||||
static bool isAbsolutePath (const String& path);
|
||||
|
||||
/** Creates a file that simply contains this string, without doing the sanity-checking
|
||||
that the normal constructors do.
|
||||
|
||||
Best to avoid this unless you really know what you're doing.
|
||||
*/
|
||||
static File createFileWithoutCheckingPath (const String& absolutePath) noexcept;
|
||||
|
||||
/** Adds a separator character to the end of a path if it doesn't already have one. */
|
||||
static String addTrailingSeparator (const String& path);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
String fullPath;
|
||||
|
||||
static String parseAbsolutePath (const String&);
|
||||
String getPathUpToLastSlash() const;
|
||||
|
||||
Result createDirectoryInternal (const String&) const;
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
std::int64_t beast_fileSetPosition (void* handle, std::int64_t pos);
|
||||
|
||||
//==============================================================================
|
||||
FileInputStream::FileInputStream (const File& f)
|
||||
: file (f),
|
||||
fileHandle (nullptr),
|
||||
currentPosition (0),
|
||||
status (Result::ok()),
|
||||
needToSeek (true)
|
||||
{
|
||||
openHandle();
|
||||
}
|
||||
|
||||
FileInputStream::~FileInputStream()
|
||||
{
|
||||
closeHandle();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
std::int64_t FileInputStream::getTotalLength()
|
||||
{
|
||||
return file.getSize();
|
||||
}
|
||||
|
||||
int FileInputStream::read (void* buffer, int bytesToRead)
|
||||
{
|
||||
bassert (openedOk());
|
||||
bassert (buffer != nullptr && bytesToRead >= 0);
|
||||
|
||||
if (needToSeek)
|
||||
{
|
||||
if (beast_fileSetPosition (fileHandle, currentPosition) < 0)
|
||||
return 0;
|
||||
|
||||
needToSeek = false;
|
||||
}
|
||||
|
||||
const size_t num = readInternal (buffer, (size_t) bytesToRead);
|
||||
currentPosition += num;
|
||||
|
||||
return (int) num;
|
||||
}
|
||||
|
||||
bool FileInputStream::isExhausted()
|
||||
{
|
||||
return currentPosition >= getTotalLength();
|
||||
}
|
||||
|
||||
std::int64_t FileInputStream::getPosition()
|
||||
{
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
bool FileInputStream::setPosition (std::int64_t pos)
|
||||
{
|
||||
bassert (openedOk());
|
||||
|
||||
if (pos != currentPosition)
|
||||
{
|
||||
pos = blimit ((std::int64_t) 0, getTotalLength(), pos);
|
||||
|
||||
needToSeek |= (currentPosition != pos);
|
||||
currentPosition = pos;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -1,94 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_FILES_FILEINPUTSTREAM_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_FILES_FILEINPUTSTREAM_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
An input stream that reads from a local file.
|
||||
|
||||
@see InputStream, FileOutputStream, File::createInputStream
|
||||
*/
|
||||
class FileInputStream
|
||||
: public InputStream
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a FileInputStream.
|
||||
|
||||
@param fileToRead the file to read from - if the file can't be accessed for some
|
||||
reason, then the stream will just contain no data
|
||||
*/
|
||||
explicit FileInputStream (const File& fileToRead);
|
||||
|
||||
/** Destructor. */
|
||||
~FileInputStream();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the file that this stream is reading from. */
|
||||
const File& getFile() const noexcept { return file; }
|
||||
|
||||
/** Returns the status of the file stream.
|
||||
The result will be ok if the file opened successfully. If an error occurs while
|
||||
opening or reading from the file, this will contain an error message.
|
||||
*/
|
||||
const Result& getStatus() const noexcept { return status; }
|
||||
|
||||
/** Returns true if the stream couldn't be opened for some reason.
|
||||
@see getResult()
|
||||
*/
|
||||
bool failedToOpen() const noexcept { return status.failed(); }
|
||||
|
||||
/** Returns true if the stream opened without problems.
|
||||
@see getResult()
|
||||
*/
|
||||
bool openedOk() const noexcept { return status.wasOk(); }
|
||||
|
||||
|
||||
//==============================================================================
|
||||
std::int64_t getTotalLength();
|
||||
int read (void* destBuffer, int maxBytesToRead);
|
||||
bool isExhausted();
|
||||
std::int64_t getPosition();
|
||||
bool setPosition (std::int64_t pos);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
File file;
|
||||
void* fileHandle;
|
||||
std::int64_t currentPosition;
|
||||
Result status;
|
||||
bool needToSeek;
|
||||
|
||||
void openHandle();
|
||||
void closeHandle();
|
||||
size_t readInternal (void* buffer, size_t numBytes);
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_FILEINPUTSTREAM_H_INCLUDED
|
||||
@@ -1,137 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
std::int64_t beast_fileSetPosition (void* handle, std::int64_t pos);
|
||||
|
||||
//==============================================================================
|
||||
FileOutputStream::FileOutputStream (const File& f, const size_t bufferSizeToUse)
|
||||
: file (f),
|
||||
fileHandle (nullptr),
|
||||
status (Result::ok()),
|
||||
currentPosition (0),
|
||||
bufferSize (bufferSizeToUse),
|
||||
bytesInBuffer (0),
|
||||
buffer (std::max (bufferSizeToUse, (size_t) 16))
|
||||
{
|
||||
openHandle();
|
||||
}
|
||||
|
||||
FileOutputStream::~FileOutputStream()
|
||||
{
|
||||
flushBuffer();
|
||||
flushInternal();
|
||||
closeHandle();
|
||||
}
|
||||
|
||||
std::int64_t FileOutputStream::getPosition()
|
||||
{
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
bool FileOutputStream::setPosition (std::int64_t newPosition)
|
||||
{
|
||||
if (newPosition != currentPosition)
|
||||
{
|
||||
flushBuffer();
|
||||
currentPosition = beast_fileSetPosition (fileHandle, newPosition);
|
||||
}
|
||||
|
||||
return newPosition == currentPosition;
|
||||
}
|
||||
|
||||
bool FileOutputStream::flushBuffer()
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
if (bytesInBuffer > 0)
|
||||
{
|
||||
ok = (writeInternal (buffer, bytesInBuffer) == (std::ptrdiff_t) bytesInBuffer);
|
||||
bytesInBuffer = 0;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void FileOutputStream::flush()
|
||||
{
|
||||
flushBuffer();
|
||||
flushInternal();
|
||||
}
|
||||
|
||||
bool FileOutputStream::write (const void* const src, const size_t numBytes)
|
||||
{
|
||||
bassert (src != nullptr && ((std::ptrdiff_t) numBytes) >= 0);
|
||||
|
||||
if (bytesInBuffer + numBytes < bufferSize)
|
||||
{
|
||||
memcpy (buffer + bytesInBuffer, src, numBytes);
|
||||
bytesInBuffer += numBytes;
|
||||
currentPosition += numBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! flushBuffer())
|
||||
return false;
|
||||
|
||||
if (numBytes < bufferSize)
|
||||
{
|
||||
memcpy (buffer + bytesInBuffer, src, numBytes);
|
||||
bytesInBuffer += numBytes;
|
||||
currentPosition += numBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::ptrdiff_t bytesWritten = writeInternal (src, numBytes);
|
||||
|
||||
if (bytesWritten < 0)
|
||||
return false;
|
||||
|
||||
currentPosition += bytesWritten;
|
||||
return bytesWritten == (std::ptrdiff_t) numBytes;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileOutputStream::writeRepeatedByte (std::uint8_t byte, size_t numBytes)
|
||||
{
|
||||
bassert (((std::ptrdiff_t) numBytes) >= 0);
|
||||
|
||||
if (bytesInBuffer + numBytes < bufferSize)
|
||||
{
|
||||
memset (buffer + bytesInBuffer, byte, numBytes);
|
||||
bytesInBuffer += numBytes;
|
||||
currentPosition += numBytes;
|
||||
return true;
|
||||
}
|
||||
|
||||
return OutputStream::writeRepeatedByte (byte, numBytes);
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -1,112 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_FILES_FILEOUTPUTSTREAM_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_FILES_FILEOUTPUTSTREAM_H_INCLUDED
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
An output stream that writes into a local file.
|
||||
|
||||
@see OutputStream, FileInputStream, File::createOutputStream
|
||||
*/
|
||||
class FileOutputStream
|
||||
: public OutputStream
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a FileOutputStream.
|
||||
|
||||
If the file doesn't exist, it will first be created. If the file can't be
|
||||
created or opened, the failedToOpen() method will return
|
||||
true.
|
||||
|
||||
If the file already exists when opened, the stream's write-postion will
|
||||
be set to the end of the file. To overwrite an existing file,
|
||||
use File::deleteFile() before opening the stream, or use setPosition(0)
|
||||
after it's opened (although this won't truncate the file).
|
||||
*/
|
||||
FileOutputStream (const File& fileToWriteTo,
|
||||
size_t bufferSizeToUse = 16384);
|
||||
|
||||
/** Destructor. */
|
||||
~FileOutputStream();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the file that this stream is writing to.
|
||||
*/
|
||||
const File& getFile() const { return file; }
|
||||
|
||||
/** Returns the status of the file stream.
|
||||
The result will be ok if the file opened successfully. If an error occurs while
|
||||
opening or writing to the file, this will contain an error message.
|
||||
*/
|
||||
const Result& getStatus() const noexcept { return status; }
|
||||
|
||||
/** Returns true if the stream couldn't be opened for some reason.
|
||||
@see getResult()
|
||||
*/
|
||||
bool failedToOpen() const noexcept { return status.failed(); }
|
||||
|
||||
/** Returns true if the stream opened without problems.
|
||||
@see getResult()
|
||||
*/
|
||||
bool openedOk() const noexcept { return status.wasOk(); }
|
||||
|
||||
/** Attempts to truncate the file to the current write position.
|
||||
To truncate a file to a specific size, first use setPosition() to seek to the
|
||||
appropriate location, and then call this method.
|
||||
*/
|
||||
Result truncate();
|
||||
|
||||
//==============================================================================
|
||||
void flush() override;
|
||||
std::int64_t getPosition() override;
|
||||
bool setPosition (std::int64_t) override;
|
||||
bool write (const void*, size_t) override;
|
||||
bool writeRepeatedByte (std::uint8_t byte, size_t numTimesToRepeat) override;
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
File file;
|
||||
void* fileHandle;
|
||||
Result status;
|
||||
std::int64_t currentPosition;
|
||||
size_t bufferSize, bytesInBuffer;
|
||||
HeapBlock <char> buffer;
|
||||
|
||||
void openHandle();
|
||||
void closeHandle();
|
||||
void flushInternal();
|
||||
bool flushBuffer();
|
||||
std::int64_t setPositionInternal (std::int64_t);
|
||||
std::ptrdiff_t writeInternal (const void*, size_t);
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -24,8 +24,6 @@
|
||||
#ifndef BEAST_MODULE_CORE_LOGGING_LOGGER_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_LOGGING_LOGGER_H_INCLUDED
|
||||
|
||||
#include <beast/strings/String.h>
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
|
||||
@@ -1,412 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
MemoryBlock::MemoryBlock() noexcept
|
||||
: size (0)
|
||||
{
|
||||
}
|
||||
|
||||
MemoryBlock::MemoryBlock (const size_t initialSize, const bool initialiseToZero)
|
||||
{
|
||||
if (initialSize > 0)
|
||||
{
|
||||
size = initialSize;
|
||||
data.allocate (initialSize, initialiseToZero);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
MemoryBlock::MemoryBlock (const MemoryBlock& other)
|
||||
: size (other.size)
|
||||
{
|
||||
if (size > 0)
|
||||
{
|
||||
bassert (other.data != nullptr);
|
||||
data.malloc (size);
|
||||
memcpy (data, other.data, size);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryBlock::MemoryBlock (const void* const dataToInitialiseFrom, const size_t sizeInBytes)
|
||||
: size (sizeInBytes)
|
||||
{
|
||||
bassert (((std::ptrdiff_t) sizeInBytes) >= 0);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
bassert (dataToInitialiseFrom != nullptr); // non-zero size, but a zero pointer passed-in?
|
||||
|
||||
data.malloc (size);
|
||||
|
||||
if (dataToInitialiseFrom != nullptr)
|
||||
memcpy (data, dataToInitialiseFrom, size);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryBlock::~MemoryBlock() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
MemoryBlock& MemoryBlock::operator= (const MemoryBlock& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
setSize (other.size, false);
|
||||
memcpy (data, other.data, size);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
MemoryBlock::MemoryBlock (MemoryBlock&& other) noexcept
|
||||
: data (static_cast <HeapBlock <char>&&> (other.data)),
|
||||
size (other.size)
|
||||
{
|
||||
}
|
||||
|
||||
MemoryBlock& MemoryBlock::operator= (MemoryBlock&& other) noexcept
|
||||
{
|
||||
data = static_cast <HeapBlock <char>&&> (other.data);
|
||||
size = other.size;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//==============================================================================
|
||||
bool MemoryBlock::operator== (const MemoryBlock& other) const noexcept
|
||||
{
|
||||
return matches (other.data, other.size);
|
||||
}
|
||||
|
||||
bool MemoryBlock::operator!= (const MemoryBlock& other) const noexcept
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
bool MemoryBlock::matches (const void* dataToCompare, size_t dataSize) const noexcept
|
||||
{
|
||||
return size == dataSize
|
||||
&& memcmp (data, dataToCompare, size) == 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// this will resize the block to this size
|
||||
void MemoryBlock::setSize (const size_t newSize, const bool initialiseToZero)
|
||||
{
|
||||
if (size != newSize)
|
||||
{
|
||||
if (newSize <= 0)
|
||||
{
|
||||
data.free_up();
|
||||
size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data != nullptr)
|
||||
{
|
||||
data.reallocate (newSize);
|
||||
|
||||
if (initialiseToZero && (newSize > size))
|
||||
zeromem (data + size, newSize - size);
|
||||
}
|
||||
else
|
||||
{
|
||||
data.allocate (newSize, initialiseToZero);
|
||||
}
|
||||
|
||||
size = newSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBlock::ensureSize (const size_t minimumSize, const bool initialiseToZero)
|
||||
{
|
||||
if (size < minimumSize)
|
||||
setSize (minimumSize, initialiseToZero);
|
||||
}
|
||||
|
||||
void MemoryBlock::swapWith (MemoryBlock& other) noexcept
|
||||
{
|
||||
std::swap (size, other.size);
|
||||
data.swapWith (other.data);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void MemoryBlock::fillWith (const std::uint8_t value) noexcept
|
||||
{
|
||||
memset (data, (int) value, size);
|
||||
}
|
||||
|
||||
void MemoryBlock::append (const void* const srcData, const size_t numBytes)
|
||||
{
|
||||
if (numBytes > 0)
|
||||
{
|
||||
bassert (srcData != nullptr); // this must not be null!
|
||||
const size_t oldSize = size;
|
||||
setSize (size + numBytes);
|
||||
memcpy (data + oldSize, srcData, numBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBlock::replaceWith (const void* const srcData, const size_t numBytes)
|
||||
{
|
||||
if (numBytes > 0)
|
||||
{
|
||||
bassert (srcData != nullptr); // this must not be null!
|
||||
setSize (numBytes);
|
||||
memcpy (data, srcData, numBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBlock::insert (const void* const srcData, const size_t numBytes, size_t insertPosition)
|
||||
{
|
||||
if (numBytes > 0)
|
||||
{
|
||||
bassert (srcData != nullptr); // this must not be null!
|
||||
insertPosition = std::min (size, insertPosition);
|
||||
const size_t trailingDataSize = size - insertPosition;
|
||||
setSize (size + numBytes, false);
|
||||
|
||||
if (trailingDataSize > 0)
|
||||
memmove (data + insertPosition + numBytes,
|
||||
data + insertPosition,
|
||||
trailingDataSize);
|
||||
|
||||
memcpy (data + insertPosition, srcData, numBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBlock::removeSection (const size_t startByte, const size_t numBytesToRemove)
|
||||
{
|
||||
if (startByte + numBytesToRemove >= size)
|
||||
{
|
||||
setSize (startByte);
|
||||
}
|
||||
else if (numBytesToRemove > 0)
|
||||
{
|
||||
memmove (data + startByte,
|
||||
data + startByte + numBytesToRemove,
|
||||
size - (startByte + numBytesToRemove));
|
||||
|
||||
setSize (size - numBytesToRemove);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBlock::copyFrom (const void* const src, int offset, size_t num) noexcept
|
||||
{
|
||||
const char* d = static_cast<const char*> (src);
|
||||
|
||||
if (offset < 0)
|
||||
{
|
||||
d -= offset;
|
||||
num += (size_t) -offset;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
if ((size_t) offset + num > size)
|
||||
num = size - (size_t) offset;
|
||||
|
||||
if (num > 0)
|
||||
memcpy (data + offset, d, num);
|
||||
}
|
||||
|
||||
void MemoryBlock::copyTo (void* const dst, int offset, size_t num) const noexcept
|
||||
{
|
||||
char* d = static_cast<char*> (dst);
|
||||
|
||||
if (offset < 0)
|
||||
{
|
||||
zeromem (d, (size_t) -offset);
|
||||
d -= offset;
|
||||
num -= (size_t) -offset;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
if ((size_t) offset + num > size)
|
||||
{
|
||||
const size_t newNum = size - (size_t) offset;
|
||||
zeromem (d + newNum, num - newNum);
|
||||
num = newNum;
|
||||
}
|
||||
|
||||
if (num > 0)
|
||||
memcpy (d, data + offset, num);
|
||||
}
|
||||
|
||||
String MemoryBlock::toString() const
|
||||
{
|
||||
return String (CharPointer_UTF8 (data), size);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int MemoryBlock::getBitRange (const size_t bitRangeStart, size_t numBits) const noexcept
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
size_t byte = bitRangeStart >> 3;
|
||||
size_t offsetInByte = bitRangeStart & 7;
|
||||
size_t bitsSoFar = 0;
|
||||
|
||||
while (numBits > 0 && (size_t) byte < size)
|
||||
{
|
||||
const size_t bitsThisTime = std::min (numBits, 8 - offsetInByte);
|
||||
const int mask = (0xff >> (8 - bitsThisTime)) << offsetInByte;
|
||||
|
||||
res |= (((data[byte] & mask) >> offsetInByte) << bitsSoFar);
|
||||
|
||||
bitsSoFar += bitsThisTime;
|
||||
numBits -= bitsThisTime;
|
||||
++byte;
|
||||
offsetInByte = 0;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void MemoryBlock::setBitRange (const size_t bitRangeStart, size_t numBits, int bitsToSet) noexcept
|
||||
{
|
||||
size_t byte = bitRangeStart >> 3;
|
||||
size_t offsetInByte = bitRangeStart & 7;
|
||||
std::uint32_t mask = ~((((std::uint32_t) 0xffffffff) << (32 - numBits)) >> (32 - numBits));
|
||||
|
||||
while (numBits > 0 && (size_t) byte < size)
|
||||
{
|
||||
const size_t bitsThisTime = std::min (numBits, 8 - offsetInByte);
|
||||
|
||||
const std::uint32_t tempMask = (mask << offsetInByte) | ~((((std::uint32_t) 0xffffffff) >> offsetInByte) << offsetInByte);
|
||||
const std::uint32_t tempBits = (std::uint32_t) bitsToSet << offsetInByte;
|
||||
|
||||
data[byte] = (char) (((std::uint32_t) data[byte] & tempMask) | tempBits);
|
||||
|
||||
++byte;
|
||||
numBits -= bitsThisTime;
|
||||
bitsToSet >>= bitsThisTime;
|
||||
mask >>= bitsThisTime;
|
||||
offsetInByte = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void MemoryBlock::loadFromHexString (const String& hex)
|
||||
{
|
||||
ensureSize ((size_t) hex.length() >> 1);
|
||||
char* dest = data;
|
||||
String::CharPointerType t (hex.getCharPointer());
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int byte = 0;
|
||||
|
||||
for (int loop = 2; --loop >= 0;)
|
||||
{
|
||||
byte <<= 4;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const beast_wchar c = t.getAndAdvance();
|
||||
|
||||
if (c >= '0' && c <= '9') { byte |= c - '0'; break; }
|
||||
if (c >= 'a' && c <= 'z') { byte |= c - ('a' - 10); break; }
|
||||
if (c >= 'A' && c <= 'Z') { byte |= c - ('A' - 10); break; }
|
||||
|
||||
if (c == 0)
|
||||
{
|
||||
setSize (static_cast <size_t> (dest - data));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*dest++ = (char) byte;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
static char const* const base64EncodingTable = ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+";
|
||||
|
||||
String MemoryBlock::toBase64Encoding() const
|
||||
{
|
||||
const size_t numChars = ((size << 3) + 5) / 6;
|
||||
|
||||
String destString ((unsigned int) size); // store the length, followed by a '.', and then the data.
|
||||
const int initialLen = destString.length();
|
||||
destString.preallocateBytes (sizeof (String::CharPointerType::CharType) * (size_t) initialLen + 2 + numChars);
|
||||
|
||||
String::CharPointerType d (destString.getCharPointer());
|
||||
d += initialLen;
|
||||
d.write ('.');
|
||||
|
||||
for (size_t i = 0; i < numChars; ++i)
|
||||
d.write ((beast_wchar) (std::uint8_t) base64EncodingTable [getBitRange (i * 6, 6)]);
|
||||
|
||||
d.writeNull();
|
||||
return destString;
|
||||
}
|
||||
|
||||
bool MemoryBlock::fromBase64Encoding (const String& s)
|
||||
{
|
||||
const int startPos = s.indexOfChar ('.') + 1;
|
||||
|
||||
if (startPos <= 0)
|
||||
return false;
|
||||
|
||||
const int numBytesNeeded = s.substring (0, startPos - 1).getIntValue();
|
||||
|
||||
setSize ((size_t) numBytesNeeded, true);
|
||||
|
||||
const int numChars = s.length() - startPos;
|
||||
|
||||
String::CharPointerType srcChars (s.getCharPointer());
|
||||
srcChars += startPos;
|
||||
int pos = 0;
|
||||
|
||||
for (int i = 0; i < numChars; ++i)
|
||||
{
|
||||
const char c = (char) srcChars.getAndAdvance();
|
||||
|
||||
for (int j = 0; j < 64; ++j)
|
||||
{
|
||||
if (base64EncodingTable[j] == c)
|
||||
{
|
||||
setBitRange ((size_t) pos, 6, j);
|
||||
pos += 6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -1,275 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_MEMORY_MEMORYBLOCK_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_MEMORY_MEMORYBLOCK_H_INCLUDED
|
||||
|
||||
#include <beast/HeapBlock.h>
|
||||
#include <beast/strings/String.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A class to hold a resizable block of raw data.
|
||||
|
||||
*/
|
||||
class MemoryBlock
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Create an uninitialised block with 0 size. */
|
||||
MemoryBlock() noexcept;
|
||||
|
||||
/** Creates a memory block with a given initial size.
|
||||
|
||||
@param initialSize the size of block to create
|
||||
@param initialiseToZero whether to clear the memory or just leave it uninitialised
|
||||
*/
|
||||
MemoryBlock (const size_t initialSize,
|
||||
bool initialiseToZero = false);
|
||||
|
||||
/** Creates a copy of another memory block. */
|
||||
MemoryBlock (const MemoryBlock& other);
|
||||
|
||||
/** Creates a memory block using a copy of a block of data.
|
||||
|
||||
@param dataToInitialiseFrom some data to copy into this block
|
||||
@param sizeInBytes how much space to use
|
||||
*/
|
||||
MemoryBlock (const void* dataToInitialiseFrom, size_t sizeInBytes);
|
||||
|
||||
/** Destructor. */
|
||||
~MemoryBlock() noexcept;
|
||||
|
||||
/** Copies another memory block onto this one.
|
||||
|
||||
This block will be resized and copied to exactly match the other one.
|
||||
*/
|
||||
MemoryBlock& operator= (const MemoryBlock& other);
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
MemoryBlock (MemoryBlock&& other) noexcept;
|
||||
MemoryBlock& operator= (MemoryBlock&& other) noexcept;
|
||||
#endif
|
||||
|
||||
// Standard container interface
|
||||
using iterator = char*;
|
||||
using const_iterator = char const*;
|
||||
inline iterator begin () noexcept { return static_cast <iterator> (getData ()); }
|
||||
inline iterator end () noexcept { return addBytesToPointer (begin (), size); }
|
||||
inline const_iterator cbegin () const noexcept { return static_cast <const_iterator> (getConstData ()); }
|
||||
inline const_iterator cend () const noexcept { return addBytesToPointer (cbegin (), size); }
|
||||
|
||||
//==============================================================================
|
||||
/** Compares two memory blocks.
|
||||
|
||||
@returns true only if the two blocks are the same size and have identical contents.
|
||||
*/
|
||||
bool operator== (const MemoryBlock& other) const noexcept;
|
||||
|
||||
/** Compares two memory blocks.
|
||||
|
||||
@returns true if the two blocks are different sizes or have different contents.
|
||||
*/
|
||||
bool operator!= (const MemoryBlock& other) const noexcept;
|
||||
|
||||
/** Returns true if the data in this MemoryBlock matches the raw bytes passed-in.
|
||||
*/
|
||||
bool matches (const void* data, size_t dataSize) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a void pointer to the data.
|
||||
|
||||
Note that the pointer returned will probably become invalid when the
|
||||
block is resized.
|
||||
*/
|
||||
void* getData() const noexcept
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
/** Returns a void pointer to data as unmodifiable.
|
||||
|
||||
Note that the pointer returned will probably become invalid when the
|
||||
block is resized.
|
||||
*/
|
||||
void const* getConstData() const noexcept
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
/** Returns a byte from the memory block.
|
||||
|
||||
This returns a reference, so you can also use it to set a byte.
|
||||
*/
|
||||
template <typename Type>
|
||||
char& operator[] (const Type offset) const noexcept { return data [offset]; }
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the block's current allocated size, in bytes. */
|
||||
size_t getSize() const noexcept { return size; }
|
||||
|
||||
/** Resizes the memory block.
|
||||
|
||||
This will try to keep as much of the block's current content as it can,
|
||||
and can optionally be made to clear any new space that gets allocated at
|
||||
the end of the block.
|
||||
|
||||
@param newSize the new desired size for the block
|
||||
@param initialiseNewSpaceToZero if the block gets enlarged, this determines
|
||||
whether to clear the new section or just leave it
|
||||
uninitialised
|
||||
@see ensureSize
|
||||
*/
|
||||
void setSize (const size_t newSize,
|
||||
bool initialiseNewSpaceToZero = false);
|
||||
|
||||
/** Increases the block's size only if it's smaller than a given size.
|
||||
|
||||
@param minimumSize if the block is already bigger than this size, no action
|
||||
will be taken; otherwise it will be increased to this size
|
||||
@param initialiseNewSpaceToZero if the block gets enlarged, this determines
|
||||
whether to clear the new section or just leave it
|
||||
uninitialised
|
||||
@see setSize
|
||||
*/
|
||||
void ensureSize (const size_t minimumSize,
|
||||
bool initialiseNewSpaceToZero = false);
|
||||
|
||||
//==============================================================================
|
||||
/** Fills the entire memory block with a repeated byte value.
|
||||
|
||||
This is handy for clearing a block of memory to zero.
|
||||
*/
|
||||
void fillWith (std::uint8_t valueToUse) noexcept;
|
||||
|
||||
/** Adds another block of data to the end of this one.
|
||||
The data pointer must not be null. This block's size will be increased accordingly.
|
||||
*/
|
||||
void append (const void* data, size_t numBytes);
|
||||
|
||||
/** Resizes this block to the given size and fills its contents from the supplied buffer.
|
||||
The data pointer must not be null.
|
||||
*/
|
||||
void replaceWith (const void* data, size_t numBytes);
|
||||
|
||||
/** Inserts some data into the block.
|
||||
The dataToInsert pointer must not be null. This block's size will be increased accordingly.
|
||||
If the insert position lies outside the valid range of the block, it will be clipped to
|
||||
within the range before being used.
|
||||
*/
|
||||
void insert (const void* dataToInsert, size_t numBytesToInsert, size_t insertPosition);
|
||||
|
||||
/** Chops out a section of the block.
|
||||
|
||||
This will remove a section of the memory block and close the gap around it,
|
||||
shifting any subsequent data downwards and reducing the size of the block.
|
||||
|
||||
If the range specified goes beyond the size of the block, it will be clipped.
|
||||
*/
|
||||
void removeSection (size_t startByte, size_t numBytesToRemove);
|
||||
|
||||
//==============================================================================
|
||||
/** Copies data into this MemoryBlock from a memory address.
|
||||
|
||||
@param srcData the memory location of the data to copy into this block
|
||||
@param destinationOffset the offset in this block at which the data being copied should begin
|
||||
@param numBytes how much to copy in (if this goes beyond the size of the memory block,
|
||||
it will be clipped so not to do anything nasty)
|
||||
*/
|
||||
void copyFrom (const void* srcData,
|
||||
int destinationOffset,
|
||||
size_t numBytes) noexcept;
|
||||
|
||||
/** Copies data from this MemoryBlock to a memory address.
|
||||
|
||||
@param destData the memory location to write to
|
||||
@param sourceOffset the offset within this block from which the copied data will be read
|
||||
@param numBytes how much to copy (if this extends beyond the limits of the memory block,
|
||||
zeros will be used for that portion of the data)
|
||||
*/
|
||||
void copyTo (void* destData,
|
||||
int sourceOffset,
|
||||
size_t numBytes) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Exchanges the contents of this and another memory block.
|
||||
No actual copying is required for this, so it's very fast.
|
||||
*/
|
||||
void swapWith (MemoryBlock& other) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Attempts to parse the contents of the block as a zero-terminated UTF8 string. */
|
||||
String toString() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Parses a string of hexadecimal numbers and writes this data into the memory block.
|
||||
|
||||
The block will be resized to the number of valid bytes read from the string.
|
||||
Non-hex characters in the string will be ignored.
|
||||
|
||||
@see String::toHexString()
|
||||
*/
|
||||
void loadFromHexString (const String& sourceHexString);
|
||||
|
||||
//==============================================================================
|
||||
/** Sets a number of bits in the memory block, treating it as a long binary sequence. */
|
||||
void setBitRange (size_t bitRangeStart,
|
||||
size_t numBits,
|
||||
int binaryNumberToApply) noexcept;
|
||||
|
||||
/** Reads a number of bits from the memory block, treating it as one long binary sequence */
|
||||
int getBitRange (size_t bitRangeStart,
|
||||
size_t numBitsToRead) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a string of characters that represent the binary contents of this block.
|
||||
|
||||
Uses a 64-bit encoding system to allow binary data to be turned into a string
|
||||
of simple non-extended characters, e.g. for storage in XML.
|
||||
|
||||
@see fromBase64Encoding
|
||||
*/
|
||||
String toBase64Encoding() const;
|
||||
|
||||
/** Takes a string of encoded characters and turns it into binary data.
|
||||
|
||||
The string passed in must have been created by to64BitEncoding(), and this
|
||||
block will be resized to recreate the original data block.
|
||||
|
||||
@see toBase64Encoding
|
||||
*/
|
||||
bool fromBase64Encoding (const String& encodedString);
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
HeapBlock <char> data;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
Result::Result() noexcept {}
|
||||
|
||||
Result::Result (const String& message) noexcept
|
||||
: errorMessage (message)
|
||||
{
|
||||
}
|
||||
|
||||
Result::Result (const Result& other)
|
||||
: errorMessage (other.errorMessage)
|
||||
{
|
||||
}
|
||||
|
||||
Result& Result::operator= (const Result& other)
|
||||
{
|
||||
errorMessage = other.errorMessage;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
Result::Result (Result&& other) noexcept
|
||||
: errorMessage (static_cast <String&&> (other.errorMessage))
|
||||
{
|
||||
}
|
||||
|
||||
Result& Result::operator= (Result&& other) noexcept
|
||||
{
|
||||
errorMessage = static_cast <String&&> (other.errorMessage);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Result::operator== (const Result& other) const noexcept
|
||||
{
|
||||
return errorMessage == other.errorMessage;
|
||||
}
|
||||
|
||||
bool Result::operator!= (const Result& other) const noexcept
|
||||
{
|
||||
return errorMessage != other.errorMessage;
|
||||
}
|
||||
|
||||
Result Result::fail (const String& errorMessage) noexcept
|
||||
{
|
||||
return Result (errorMessage.isEmpty() ? "Unknown error" : errorMessage);
|
||||
}
|
||||
|
||||
const String& Result::getErrorMessage() const noexcept
|
||||
{
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
bool Result::wasOk() const noexcept { return errorMessage.isEmpty(); }
|
||||
Result::operator bool() const noexcept { return errorMessage.isEmpty(); }
|
||||
bool Result::failed() const noexcept { return errorMessage.isNotEmpty(); }
|
||||
bool Result::operator!() const noexcept { return errorMessage.isNotEmpty(); }
|
||||
|
||||
} // beast
|
||||
@@ -1,122 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_MISC_RESULT_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_MISC_RESULT_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
/** Represents the 'success' or 'failure' of an operation, and holds an associated
|
||||
error message to describe the error when there's a failure.
|
||||
|
||||
E.g.
|
||||
@code
|
||||
Result myOperation()
|
||||
{
|
||||
if (doSomeKindOfFoobar())
|
||||
return Result::ok();
|
||||
else
|
||||
return Result::fail ("foobar didn't work!");
|
||||
}
|
||||
|
||||
const Result result (myOperation());
|
||||
|
||||
if (result.wasOk())
|
||||
{
|
||||
...it's all good...
|
||||
}
|
||||
else
|
||||
{
|
||||
warnUserAboutFailure ("The foobar operation failed! Error message was: "
|
||||
+ result.getErrorMessage());
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
class Result
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates and returns a 'successful' result. */
|
||||
static Result ok() noexcept { return Result(); }
|
||||
|
||||
/** Creates a 'failure' result.
|
||||
If you pass a blank error message in here, a default "Unknown Error" message
|
||||
will be used instead.
|
||||
*/
|
||||
static Result fail (const String& errorMessage) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if this result indicates a success. */
|
||||
bool wasOk() const noexcept;
|
||||
|
||||
/** Returns true if this result indicates a failure.
|
||||
You can use getErrorMessage() to retrieve the error message associated
|
||||
with the failure.
|
||||
*/
|
||||
bool failed() const noexcept;
|
||||
|
||||
/** Returns true if this result indicates a success.
|
||||
This is equivalent to calling wasOk().
|
||||
*/
|
||||
operator bool() const noexcept;
|
||||
|
||||
/** Returns true if this result indicates a failure.
|
||||
This is equivalent to calling failed().
|
||||
*/
|
||||
bool operator!() const noexcept;
|
||||
|
||||
/** Returns the error message that was set when this result was created.
|
||||
For a successful result, this will be an empty string;
|
||||
*/
|
||||
const String& getErrorMessage() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
Result (const Result&);
|
||||
Result& operator= (const Result&);
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
Result (Result&&) noexcept;
|
||||
Result& operator= (Result&&) noexcept;
|
||||
#endif
|
||||
|
||||
bool operator== (const Result& other) const noexcept;
|
||||
bool operator!= (const Result& other) const noexcept;
|
||||
|
||||
private:
|
||||
String errorMessage;
|
||||
|
||||
// The default constructor is not for public use!
|
||||
// Instead, use Result::ok() or Result::fail()
|
||||
Result() noexcept;
|
||||
explicit Result (const String&) noexcept;
|
||||
|
||||
// These casts are private to prevent people trying to use the Result object in numeric contexts
|
||||
operator int() const;
|
||||
operator void*() const;
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,185 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast
|
||||
{
|
||||
//==============================================================================
|
||||
static File resolveXDGFolder (const char* const type, const char* const fallbackFolder)
|
||||
{
|
||||
File userDirs ("~/.config/user-dirs.dirs");
|
||||
StringArray confLines;
|
||||
|
||||
if (userDirs.existsAsFile())
|
||||
{
|
||||
FileInputStream in (userDirs);
|
||||
|
||||
if (in.openedOk())
|
||||
confLines.addLines (in.readEntireStreamAsString());
|
||||
}
|
||||
|
||||
for (int i = 0; i < confLines.size(); ++i)
|
||||
{
|
||||
const String line (confLines[i].trimStart());
|
||||
|
||||
if (line.startsWith (type))
|
||||
{
|
||||
// eg. resolve XDG_MUSIC_DIR="$HOME/Music" to /home/user/Music
|
||||
const File f (line.replace ("$HOME", File ("~").getFullPathName())
|
||||
.fromFirstOccurrenceOf ("=", false, false)
|
||||
.trim().unquoted());
|
||||
|
||||
if (f.isDirectory())
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
return File (fallbackFolder);
|
||||
}
|
||||
|
||||
File File::getSpecialLocation (const SpecialLocationType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case userHomeDirectory:
|
||||
{
|
||||
const char* homeDir = getenv ("HOME");
|
||||
|
||||
if (homeDir == nullptr)
|
||||
{
|
||||
struct passwd* const pw = getpwuid (getuid());
|
||||
if (pw != nullptr)
|
||||
homeDir = pw->pw_dir;
|
||||
}
|
||||
|
||||
return File (CharPointer_UTF8 (homeDir));
|
||||
}
|
||||
|
||||
case userDocumentsDirectory: return resolveXDGFolder ("XDG_DOCUMENTS_DIR", "~");
|
||||
case userMusicDirectory: return resolveXDGFolder ("XDG_MUSIC_DIR", "~");
|
||||
case userMoviesDirectory: return resolveXDGFolder ("XDG_VIDEOS_DIR", "~");
|
||||
case userPicturesDirectory: return resolveXDGFolder ("XDG_PICTURES_DIR", "~");
|
||||
case userDesktopDirectory: return resolveXDGFolder ("XDG_DESKTOP_DIR", "~/Desktop");
|
||||
case userApplicationDataDirectory: return File ("~");
|
||||
case commonApplicationDataDirectory: return File ("/var");
|
||||
case globalApplicationsDirectory: return File ("/usr");
|
||||
|
||||
case tempDirectory:
|
||||
{
|
||||
File tmp ("/var/tmp");
|
||||
|
||||
if (! tmp.isDirectory())
|
||||
{
|
||||
tmp = "/tmp";
|
||||
|
||||
if (! tmp.isDirectory())
|
||||
tmp = File::getCurrentWorkingDirectory();
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
default:
|
||||
bassertfalse; // unknown type?
|
||||
break;
|
||||
}
|
||||
|
||||
return File::nonexistent ();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class DirectoryIterator::NativeIterator::Pimpl
|
||||
{
|
||||
public:
|
||||
Pimpl (const File& directory, const String& wildCard_)
|
||||
: parentDir (File::addTrailingSeparator (directory.getFullPathName())),
|
||||
wildCard (wildCard_),
|
||||
dir (opendir (directory.getFullPathName().toUTF8()))
|
||||
{
|
||||
}
|
||||
|
||||
Pimpl (Pimpl const&) = delete;
|
||||
Pimpl& operator= (Pimpl const&) = delete;
|
||||
|
||||
~Pimpl()
|
||||
{
|
||||
if (dir != nullptr)
|
||||
closedir (dir);
|
||||
}
|
||||
|
||||
bool next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, std::int64_t* const fileSize,
|
||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
|
||||
{
|
||||
if (dir != nullptr)
|
||||
{
|
||||
const char* wildcardUTF8 = nullptr;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
struct dirent* const de = readdir (dir);
|
||||
|
||||
if (de == nullptr)
|
||||
break;
|
||||
|
||||
if (wildcardUTF8 == nullptr)
|
||||
wildcardUTF8 = wildCard.toUTF8();
|
||||
|
||||
if (fnmatch (wildcardUTF8, de->d_name, FNM_CASEFOLD) == 0)
|
||||
{
|
||||
filenameFound = CharPointer_UTF8 (de->d_name);
|
||||
|
||||
updateStatInfoForFile (parentDir + filenameFound, isDir, fileSize, modTime, creationTime, isReadOnly);
|
||||
|
||||
if (isHidden != nullptr)
|
||||
*isHidden = filenameFound.startsWithChar ('.');
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
String parentDir, wildCard;
|
||||
DIR* dir;
|
||||
};
|
||||
|
||||
DirectoryIterator::NativeIterator::NativeIterator (const File& directory, const String& wildCard)
|
||||
: pimpl (new DirectoryIterator::NativeIterator::Pimpl (directory, wildCard))
|
||||
{
|
||||
}
|
||||
|
||||
DirectoryIterator::NativeIterator::~NativeIterator()
|
||||
{
|
||||
}
|
||||
|
||||
bool DirectoryIterator::NativeIterator::next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, std::int64_t* const fileSize,
|
||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
|
||||
{
|
||||
return pimpl->next (filenameFound, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly);
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -27,14 +27,6 @@ void outputDebugString (std::string const& text)
|
||||
std::cerr << text << std::endl;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool beast_isRunningUnderDebugger()
|
||||
{
|
||||
// XXX not implemented for FreeBSD!
|
||||
// bassertfalse; // commented out since it calls isRunningUnderDebugger recursively
|
||||
return false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
std::string getComputerName()
|
||||
{
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast
|
||||
{
|
||||
//==============================================================================
|
||||
static File resolveXDGFolder (const char* const type, const char* const fallbackFolder)
|
||||
{
|
||||
File userDirs ("~/.config/user-dirs.dirs");
|
||||
StringArray confLines;
|
||||
|
||||
if (userDirs.existsAsFile())
|
||||
{
|
||||
FileInputStream in (userDirs);
|
||||
|
||||
if (in.openedOk())
|
||||
confLines.addLines (in.readEntireStreamAsString());
|
||||
}
|
||||
|
||||
for (int i = 0; i < confLines.size(); ++i)
|
||||
{
|
||||
const String line (confLines[i].trimStart());
|
||||
|
||||
if (line.startsWith (type))
|
||||
{
|
||||
// eg. resolve XDG_MUSIC_DIR="$HOME/Music" to /home/user/Music
|
||||
const File f (line.replace ("$HOME", File ("~").getFullPathName())
|
||||
.fromFirstOccurrenceOf ("=", false, false)
|
||||
.trim().unquoted());
|
||||
|
||||
if (f.isDirectory())
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
return File (fallbackFolder);
|
||||
}
|
||||
|
||||
File File::getSpecialLocation (const SpecialLocationType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case userHomeDirectory:
|
||||
{
|
||||
const char* homeDir = getenv ("HOME");
|
||||
if (homeDir)
|
||||
return File (CharPointer_UTF8 (homeDir));
|
||||
|
||||
if (struct passwd* const pw = getpwuid (getuid()))
|
||||
return File (CharPointer_UTF8 (pw->pw_dir));
|
||||
|
||||
return File (CharPointer_UTF8 (homeDir));
|
||||
}
|
||||
|
||||
case userDocumentsDirectory: return resolveXDGFolder ("XDG_DOCUMENTS_DIR", "~");
|
||||
case userMusicDirectory: return resolveXDGFolder ("XDG_MUSIC_DIR", "~");
|
||||
case userMoviesDirectory: return resolveXDGFolder ("XDG_VIDEOS_DIR", "~");
|
||||
case userPicturesDirectory: return resolveXDGFolder ("XDG_PICTURES_DIR", "~");
|
||||
case userDesktopDirectory: return resolveXDGFolder ("XDG_DESKTOP_DIR", "~/Desktop");
|
||||
case userApplicationDataDirectory: return File ("~");
|
||||
case commonDocumentsDirectory:
|
||||
case commonApplicationDataDirectory: return File ("/var");
|
||||
case globalApplicationsDirectory: return File ("/usr");
|
||||
|
||||
case tempDirectory:
|
||||
{
|
||||
File tmp ("/var/tmp");
|
||||
|
||||
if (! tmp.isDirectory())
|
||||
{
|
||||
tmp = "/tmp";
|
||||
|
||||
if (! tmp.isDirectory())
|
||||
tmp = File::getCurrentWorkingDirectory();
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
default:
|
||||
bassertfalse; // unknown type?
|
||||
break;
|
||||
}
|
||||
|
||||
return File::nonexistent ();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class DirectoryIterator::NativeIterator::Pimpl
|
||||
{
|
||||
public:
|
||||
Pimpl (const File& directory, const String& wildCard_)
|
||||
: parentDir (File::addTrailingSeparator (directory.getFullPathName())),
|
||||
wildCard (wildCard_),
|
||||
dir (opendir (directory.getFullPathName().toUTF8()))
|
||||
{
|
||||
}
|
||||
|
||||
Pimpl (Pimpl const&) = delete;
|
||||
Pimpl& operator= (Pimpl const&) = delete;
|
||||
|
||||
~Pimpl()
|
||||
{
|
||||
if (dir != nullptr)
|
||||
closedir (dir);
|
||||
}
|
||||
|
||||
bool next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, std::int64_t* const fileSize,
|
||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
|
||||
{
|
||||
if (dir != nullptr)
|
||||
{
|
||||
const char* wildcardUTF8 = nullptr;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
struct dirent* const de = readdir (dir);
|
||||
|
||||
if (de == nullptr)
|
||||
break;
|
||||
|
||||
if (wildcardUTF8 == nullptr)
|
||||
wildcardUTF8 = wildCard.toUTF8();
|
||||
|
||||
if (fnmatch (wildcardUTF8, de->d_name, FNM_CASEFOLD) == 0)
|
||||
{
|
||||
filenameFound = CharPointer_UTF8 (de->d_name);
|
||||
|
||||
updateStatInfoForFile (parentDir + filenameFound, isDir, fileSize, modTime, creationTime, isReadOnly);
|
||||
|
||||
if (isHidden != nullptr)
|
||||
*isHidden = filenameFound.startsWithChar ('.');
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
String parentDir, wildCard;
|
||||
DIR* dir;
|
||||
};
|
||||
|
||||
DirectoryIterator::NativeIterator::NativeIterator (const File& directory, const String& wildCard_)
|
||||
: pimpl (new DirectoryIterator::NativeIterator::Pimpl (directory, wildCard_))
|
||||
{
|
||||
}
|
||||
|
||||
DirectoryIterator::NativeIterator::~NativeIterator()
|
||||
{
|
||||
}
|
||||
|
||||
bool DirectoryIterator::NativeIterator::next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, std::int64_t* const fileSize,
|
||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
|
||||
{
|
||||
return pimpl->next (filenameFound, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly);
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -29,25 +29,6 @@ void outputDebugString (std::string const& text)
|
||||
std::cerr << text << std::endl;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool beast_isRunningUnderDebugger()
|
||||
{
|
||||
static char testResult = 0;
|
||||
|
||||
if (testResult == 0)
|
||||
{
|
||||
testResult = (char) ptrace (PT_TRACE_ME, 0, 0, 0);
|
||||
|
||||
if (testResult >= 0)
|
||||
{
|
||||
ptrace (PT_DETACH, 0, (caddr_t) 1, 0);
|
||||
testResult = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return testResult < 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
std::string getComputerName()
|
||||
{
|
||||
|
||||
@@ -1,237 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
/*
|
||||
Note that a lot of methods that you'd expect to find in this file actually
|
||||
live in beast_posix_SharedCode.h!
|
||||
*/
|
||||
|
||||
//==============================================================================
|
||||
namespace FileHelpers
|
||||
{
|
||||
static bool isFileOnDriveType (const File& f, const char* const* types)
|
||||
{
|
||||
struct statfs buf;
|
||||
|
||||
if (beast_doStatFS (f, buf))
|
||||
{
|
||||
const String type (buf.f_fstypename);
|
||||
|
||||
while (*types != 0)
|
||||
if (type.equalsIgnoreCase (*types++))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isHiddenFile (const String& path)
|
||||
{
|
||||
#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
|
||||
BEAST_AUTORELEASEPOOL
|
||||
{
|
||||
NSNumber* hidden = nil;
|
||||
NSError* err = nil;
|
||||
|
||||
return [[NSURL fileURLWithPath: beastStringToNS (path)]
|
||||
getResourceValue: &hidden forKey: NSURLIsHiddenKey error: &err]
|
||||
&& [hidden boolValue];
|
||||
}
|
||||
#elif BEAST_IOS
|
||||
return File (path).getFileName().startsWithChar ('.');
|
||||
#else
|
||||
FSRef ref;
|
||||
LSItemInfoRecord info;
|
||||
|
||||
return FSPathMakeRefWithOptions ((const UInt8*) path.toRawUTF8(), kFSPathMakeRefDoNotFollowLeafSymlink, &ref, 0) == noErr
|
||||
&& LSCopyItemInfoForRef (&ref, kLSRequestBasicFlagsOnly, &info) == noErr
|
||||
&& (info.flags & kLSItemInfoIsInvisible) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BEAST_IOS
|
||||
String getIOSSystemLocation (NSSearchPathDirectory type)
|
||||
{
|
||||
return nsStringToBeast ([NSSearchPathForDirectoriesInDomains (type, NSUserDomainMask, YES)
|
||||
objectAtIndex: 0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool launchExecutable (const String& pathAndArguments)
|
||||
{
|
||||
const char* const argv[4] = { "/bin/sh", "-c", pathAndArguments.toUTF8(), 0 };
|
||||
|
||||
const int cpid = fork();
|
||||
|
||||
if (cpid == 0)
|
||||
{
|
||||
// Child process
|
||||
if (execve (argv[0], (char**) argv, 0) < 0)
|
||||
exit (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cpid < 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
File File::getSpecialLocation (const SpecialLocationType type)
|
||||
{
|
||||
BEAST_AUTORELEASEPOOL
|
||||
{
|
||||
String resultPath;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case userHomeDirectory: resultPath = nsStringToBeast (NSHomeDirectory()); break;
|
||||
|
||||
#if BEAST_IOS
|
||||
case userDocumentsDirectory: resultPath = FileHelpers::getIOSSystemLocation (NSDocumentDirectory); break;
|
||||
case userDesktopDirectory: resultPath = FileHelpers::getIOSSystemLocation (NSDesktopDirectory); break;
|
||||
|
||||
case tempDirectory:
|
||||
{
|
||||
File tmp (FileHelpers::getIOSSystemLocation (NSCachesDirectory));
|
||||
tmp = tmp.getChildFile (beast_getExecutableFile().getFileNameWithoutExtension());
|
||||
tmp.createDirectory();
|
||||
return tmp.getFullPathName();
|
||||
}
|
||||
|
||||
#else
|
||||
case userDocumentsDirectory: resultPath = "~/Documents"; break;
|
||||
case userDesktopDirectory: resultPath = "~/Desktop"; break;
|
||||
|
||||
case tempDirectory:
|
||||
{
|
||||
File tmp ("~/Library/Caches/" + beast_getExecutableFile().getFileNameWithoutExtension());
|
||||
tmp.createDirectory();
|
||||
return tmp.getFullPathName();
|
||||
}
|
||||
#endif
|
||||
case userMusicDirectory: resultPath = "~/Music"; break;
|
||||
case userMoviesDirectory: resultPath = "~/Movies"; break;
|
||||
case userPicturesDirectory: resultPath = "~/Pictures"; break;
|
||||
case userApplicationDataDirectory: resultPath = "~/Library"; break;
|
||||
case commonApplicationDataDirectory: resultPath = "/Library"; break;
|
||||
case commonDocumentsDirectory: resultPath = "/Users/Shared"; break;
|
||||
case globalApplicationsDirectory: resultPath = "/Applications"; break;
|
||||
|
||||
default:
|
||||
bassertfalse; // unknown type?
|
||||
break;
|
||||
}
|
||||
|
||||
if (resultPath.isNotEmpty())
|
||||
return File (resultPath.convertToPrecomposedUnicode());
|
||||
}
|
||||
|
||||
return File::nonexistent ();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class DirectoryIterator::NativeIterator::Pimpl
|
||||
{
|
||||
public:
|
||||
Pimpl (const File& directory, const String& wildCard_)
|
||||
: parentDir (File::addTrailingSeparator (directory.getFullPathName())),
|
||||
wildCard (wildCard_),
|
||||
enumerator (nil)
|
||||
{
|
||||
BEAST_AUTORELEASEPOOL
|
||||
{
|
||||
enumerator = [[[NSFileManager defaultManager] enumeratorAtPath: beastStringToNS (directory.getFullPathName())] retain];
|
||||
}
|
||||
}
|
||||
|
||||
Pimpl (Pimpl const&) = delete;
|
||||
Pimpl& operator= (Pimpl const&) = delete;
|
||||
|
||||
~Pimpl()
|
||||
{
|
||||
[enumerator release];
|
||||
}
|
||||
|
||||
bool next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, std::int64_t* const fileSize,
|
||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
|
||||
{
|
||||
BEAST_AUTORELEASEPOOL
|
||||
{
|
||||
const char* wildcardUTF8 = nullptr;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
NSString* file;
|
||||
if (enumerator == nil || (file = [enumerator nextObject]) == nil)
|
||||
return false;
|
||||
|
||||
[enumerator skipDescendents];
|
||||
filenameFound = nsStringToBeast (file);
|
||||
|
||||
if (wildcardUTF8 == nullptr)
|
||||
wildcardUTF8 = wildCard.toUTF8();
|
||||
|
||||
if (fnmatch (wildcardUTF8, filenameFound.toUTF8(), FNM_CASEFOLD) != 0)
|
||||
continue;
|
||||
|
||||
const String fullPath (parentDir + filenameFound);
|
||||
updateStatInfoForFile (fullPath, isDir, fileSize, modTime, creationTime, isReadOnly);
|
||||
|
||||
if (isHidden != nullptr)
|
||||
*isHidden = FileHelpers::isHiddenFile (fullPath);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
String parentDir, wildCard;
|
||||
NSDirectoryEnumerator* enumerator;
|
||||
};
|
||||
|
||||
DirectoryIterator::NativeIterator::NativeIterator (const File& directory, const String& wildcard)
|
||||
: pimpl (new DirectoryIterator::NativeIterator::Pimpl (directory, wildcard))
|
||||
{
|
||||
}
|
||||
|
||||
DirectoryIterator::NativeIterator::~NativeIterator()
|
||||
{
|
||||
}
|
||||
|
||||
bool DirectoryIterator::NativeIterator::next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, std::int64_t* const fileSize,
|
||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
|
||||
{
|
||||
return pimpl->next (filenameFound, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly);
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -1,77 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
String String::convertToPrecomposedUnicode() const
|
||||
{
|
||||
#if BEAST_IOS
|
||||
BEAST_AUTORELEASEPOOL
|
||||
{
|
||||
return nsStringToBeast ([beastStringToNS (*this) precomposedStringWithCanonicalMapping]);
|
||||
}
|
||||
#else
|
||||
UnicodeMapping map;
|
||||
|
||||
map.unicodeEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault,
|
||||
kUnicodeNoSubset,
|
||||
kTextEncodingDefaultFormat);
|
||||
|
||||
map.otherEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault,
|
||||
kUnicodeCanonicalCompVariant,
|
||||
kTextEncodingDefaultFormat);
|
||||
|
||||
map.mappingVersion = kUnicodeUseLatestMapping;
|
||||
|
||||
UnicodeToTextInfo conversionInfo = 0;
|
||||
String result;
|
||||
|
||||
if (CreateUnicodeToTextInfo (&map, &conversionInfo) == noErr)
|
||||
{
|
||||
const size_t bytesNeeded = CharPointer_UTF16::getBytesRequiredFor (getCharPointer());
|
||||
|
||||
HeapBlock <char> tempOut;
|
||||
tempOut.calloc (bytesNeeded + 4);
|
||||
|
||||
ByteCount bytesRead = 0;
|
||||
ByteCount outputBufferSize = 0;
|
||||
|
||||
if (ConvertFromUnicodeToText (conversionInfo,
|
||||
bytesNeeded, (ConstUniCharArrayPtr) toUTF16().getAddress(),
|
||||
kUnicodeDefaultDirectionMask,
|
||||
0, 0, 0, 0,
|
||||
bytesNeeded, &bytesRead,
|
||||
&outputBufferSize, tempOut) == noErr)
|
||||
{
|
||||
result = String (CharPointer_UTF16 ((CharPointer_UTF16::CharType*) tempOut.getData()));
|
||||
}
|
||||
|
||||
DisposeUnicodeToTextInfo (&conversionInfo);
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -61,29 +61,14 @@ struct RLimitInitialiser
|
||||
static RLimitInitialiser rLimitInitialiser;
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
bool beast_isRunningUnderDebugger()
|
||||
{
|
||||
static char testResult = 0;
|
||||
|
||||
if (testResult == 0)
|
||||
{
|
||||
struct kinfo_proc info;
|
||||
int m[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() };
|
||||
size_t sz = sizeof (info);
|
||||
sysctl (m, 4, &info, &sz, 0, 0);
|
||||
testResult = ((info.kp_proc.p_flag & P_TRACED) != 0) ? 1 : -1;
|
||||
}
|
||||
|
||||
return testResult > 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
std::string getComputerName()
|
||||
{
|
||||
// FIXME: Remove ".local" from the name
|
||||
char name [256] = { 0 };
|
||||
|
||||
if (gethostname (name, sizeof (name) - 1) == 0)
|
||||
return String (name).upToLastOccurrenceOf (".local", false, true).toStdString();
|
||||
return name;
|
||||
|
||||
return std::string{};
|
||||
}
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#ifndef BEAST_MODULE_CORE_NATIVE_OSX_OBJCHELPERS_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_NATIVE_OSX_OBJCHELPERS_H_INCLUDED
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
@@ -32,25 +35,17 @@ namespace beast
|
||||
*/
|
||||
namespace
|
||||
{
|
||||
//==============================================================================
|
||||
static inline String nsStringToBeast (NSString* s)
|
||||
static inline NSString* stringToNS (std::string const& s)
|
||||
{
|
||||
return CharPointer_UTF8 ([s UTF8String]);
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
// The UTF-8 encoding function for ASCII characters
|
||||
// in the range [0-127] is the identity. We are more
|
||||
// strict and require only printable characters.
|
||||
for (auto const& c : s)
|
||||
assert (isprint(c));
|
||||
#endif
|
||||
|
||||
static inline NSString* beastStringToNS (const String& s)
|
||||
{
|
||||
return [NSString stringWithUTF8String: s.toUTF8()];
|
||||
}
|
||||
|
||||
static inline NSString* nsStringLiteral (const char* const s) noexcept
|
||||
{
|
||||
return [NSString stringWithUTF8String: s];
|
||||
}
|
||||
|
||||
static inline NSString* nsEmptyString() noexcept
|
||||
{
|
||||
return [NSString string];
|
||||
return [NSString stringWithUTF8String: s.c_str()];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,340 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_NATIVE_POSIX_SHAREDCODE_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_NATIVE_POSIX_SHAREDCODE_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
CriticalSection::CriticalSection() noexcept
|
||||
{
|
||||
pthread_mutexattr_t atts;
|
||||
pthread_mutexattr_init (&atts);
|
||||
pthread_mutexattr_settype (&atts, PTHREAD_MUTEX_RECURSIVE);
|
||||
#if ! BEAST_ANDROID
|
||||
pthread_mutexattr_setprotocol (&atts, PTHREAD_PRIO_INHERIT);
|
||||
#endif
|
||||
pthread_mutex_init (&mutex, &atts);
|
||||
pthread_mutexattr_destroy (&atts);
|
||||
}
|
||||
|
||||
CriticalSection::~CriticalSection() noexcept { pthread_mutex_destroy (&mutex); }
|
||||
void CriticalSection::enter() const noexcept { pthread_mutex_lock (&mutex); }
|
||||
bool CriticalSection::tryEnter() const noexcept { return pthread_mutex_trylock (&mutex) == 0; }
|
||||
void CriticalSection::exit() const noexcept { pthread_mutex_unlock (&mutex); }
|
||||
|
||||
//==============================================================================
|
||||
const beast_wchar File::separator = '/';
|
||||
const String File::separatorString ("/");
|
||||
|
||||
//==============================================================================
|
||||
File File::getCurrentWorkingDirectory()
|
||||
{
|
||||
HeapBlock<char> heapBuffer;
|
||||
|
||||
char localBuffer [1024];
|
||||
char* cwd = getcwd (localBuffer, sizeof (localBuffer) - 1);
|
||||
size_t bufferSize = 4096;
|
||||
|
||||
while (cwd == nullptr && errno == ERANGE)
|
||||
{
|
||||
heapBuffer.malloc (bufferSize);
|
||||
cwd = getcwd (heapBuffer, bufferSize - 1);
|
||||
bufferSize += 1024;
|
||||
}
|
||||
|
||||
return File (CharPointer_UTF8 (cwd));
|
||||
}
|
||||
|
||||
// if this file doesn't exist, find a parent of it that does..
|
||||
inline
|
||||
bool beast_doStatFS (File f, struct statfs& result)
|
||||
{
|
||||
for (int i = 5; --i >= 0;)
|
||||
{
|
||||
if (f.exists())
|
||||
break;
|
||||
|
||||
f = f.getParentDirectory();
|
||||
}
|
||||
|
||||
return statfs (f.getFullPathName().toUTF8(), &result) == 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
namespace
|
||||
{
|
||||
#if BEAST_LINUX || \
|
||||
(BEAST_IOS && ! __DARWIN_ONLY_64_BIT_INO_T) // (this iOS stuff is to avoid a simulator bug)
|
||||
using beast_statStruct = struct stat64;
|
||||
#define BEAST_STAT stat64
|
||||
#else
|
||||
using beast_statStruct = struct stat;
|
||||
#define BEAST_STAT stat
|
||||
#endif
|
||||
|
||||
bool beast_stat (const String& fileName, beast_statStruct& info)
|
||||
{
|
||||
return fileName.isNotEmpty()
|
||||
&& BEAST_STAT (fileName.toUTF8(), &info) == 0;
|
||||
}
|
||||
|
||||
void updateStatInfoForFile (const String& path, bool* const isDir, std::int64_t* const fileSize,
|
||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
|
||||
{
|
||||
if (isDir != nullptr || fileSize != nullptr || modTime != nullptr || creationTime != nullptr)
|
||||
{
|
||||
beast_statStruct info;
|
||||
const bool statOk = beast_stat (path, info);
|
||||
|
||||
if (isDir != nullptr) *isDir = statOk && ((info.st_mode & S_IFDIR) != 0);
|
||||
if (fileSize != nullptr) *fileSize = statOk ? info.st_size : 0;
|
||||
if (modTime != nullptr) *modTime = Time (statOk ? (std::int64_t) info.st_mtime * 1000 : 0);
|
||||
if (creationTime != nullptr) *creationTime = Time (statOk ? (std::int64_t) info.st_ctime * 1000 : 0);
|
||||
}
|
||||
|
||||
if (isReadOnly != nullptr)
|
||||
*isReadOnly = access (path.toUTF8(), W_OK) != 0;
|
||||
}
|
||||
|
||||
Result getResultForErrno()
|
||||
{
|
||||
return Result::fail (String (strerror (errno)));
|
||||
}
|
||||
|
||||
Result getResultForReturnValue (int value)
|
||||
{
|
||||
return value == -1 ? getResultForErrno() : Result::ok();
|
||||
}
|
||||
|
||||
int getFD (void* handle) noexcept { return (int) (std::intptr_t) handle; }
|
||||
void* fdToVoidPointer (int fd) noexcept { return (void*) (std::intptr_t) fd; }
|
||||
}
|
||||
|
||||
bool File::isDirectory() const
|
||||
{
|
||||
beast_statStruct info;
|
||||
|
||||
return fullPath.isEmpty()
|
||||
|| (beast_stat (fullPath, info) && ((info.st_mode & S_IFDIR) != 0));
|
||||
}
|
||||
|
||||
bool File::exists() const
|
||||
{
|
||||
return fullPath.isNotEmpty()
|
||||
&& access (fullPath.toUTF8(), F_OK) == 0;
|
||||
}
|
||||
|
||||
bool File::existsAsFile() const
|
||||
{
|
||||
return exists() && ! isDirectory();
|
||||
}
|
||||
|
||||
std::int64_t File::getSize() const
|
||||
{
|
||||
beast_statStruct info;
|
||||
return beast_stat (fullPath, info) ? info.st_size : 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool File::deleteFile() const
|
||||
{
|
||||
if (! exists())
|
||||
return true;
|
||||
|
||||
if (isDirectory())
|
||||
return rmdir (fullPath.toUTF8()) == 0;
|
||||
|
||||
return remove (fullPath.toUTF8()) == 0;
|
||||
}
|
||||
|
||||
Result File::createDirectoryInternal (const String& fileName) const
|
||||
{
|
||||
return getResultForReturnValue (mkdir (fileName.toUTF8(), 0777));
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
std::int64_t beast_fileSetPosition (void* handle, std::int64_t pos)
|
||||
{
|
||||
if (handle != 0 && lseek (getFD (handle), pos, SEEK_SET) == pos)
|
||||
return pos;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void FileInputStream::openHandle()
|
||||
{
|
||||
const int f = open (file.getFullPathName().toUTF8(), O_RDONLY, 00644);
|
||||
|
||||
if (f != -1)
|
||||
fileHandle = fdToVoidPointer (f);
|
||||
else
|
||||
status = getResultForErrno();
|
||||
}
|
||||
|
||||
void FileInputStream::closeHandle()
|
||||
{
|
||||
if (fileHandle != 0)
|
||||
{
|
||||
close (getFD (fileHandle));
|
||||
fileHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t FileInputStream::readInternal (void* const buffer, const size_t numBytes)
|
||||
{
|
||||
std::ptrdiff_t result = 0;
|
||||
|
||||
if (fileHandle != 0)
|
||||
{
|
||||
result = ::read (getFD (fileHandle), buffer, numBytes);
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
status = getResultForErrno();
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (size_t) result;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void FileOutputStream::openHandle()
|
||||
{
|
||||
if (file.exists())
|
||||
{
|
||||
const int f = open (file.getFullPathName().toUTF8(), O_RDWR, 00644);
|
||||
|
||||
if (f != -1)
|
||||
{
|
||||
currentPosition = lseek (f, 0, SEEK_END);
|
||||
|
||||
if (currentPosition >= 0)
|
||||
{
|
||||
fileHandle = fdToVoidPointer (f);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = getResultForErrno();
|
||||
close (f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = getResultForErrno();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const int f = open (file.getFullPathName().toUTF8(), O_RDWR + O_CREAT, 00644);
|
||||
|
||||
if (f != -1)
|
||||
fileHandle = fdToVoidPointer (f);
|
||||
else
|
||||
status = getResultForErrno();
|
||||
}
|
||||
}
|
||||
|
||||
void FileOutputStream::closeHandle()
|
||||
{
|
||||
if (fileHandle != 0)
|
||||
{
|
||||
close (getFD (fileHandle));
|
||||
fileHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::ptrdiff_t FileOutputStream::writeInternal (const void* const data, const size_t numBytes)
|
||||
{
|
||||
std::ptrdiff_t result = 0;
|
||||
|
||||
if (fileHandle != 0)
|
||||
{
|
||||
result = ::write (getFD (fileHandle), data, numBytes);
|
||||
|
||||
if (result == -1)
|
||||
status = getResultForErrno();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FileOutputStream::flushInternal()
|
||||
{
|
||||
if (fileHandle != 0)
|
||||
{
|
||||
if (fsync (getFD (fileHandle)) == -1)
|
||||
status = getResultForErrno();
|
||||
|
||||
#if BEAST_ANDROID
|
||||
// This stuff tells the OS to asynchronously update the metadata
|
||||
// that the OS has cached aboud the file - this metadata is used
|
||||
// when the device is acting as a USB drive, and unless it's explicitly
|
||||
// refreshed, it'll get out of step with the real file.
|
||||
const LocalRef<jstring> t (javaString (file.getFullPathName()));
|
||||
android.activity.callVoidMethod (BeastAppActivity.scanFile, t.get());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Result FileOutputStream::truncate()
|
||||
{
|
||||
if (fileHandle == 0)
|
||||
return status;
|
||||
|
||||
flush();
|
||||
return getResultForReturnValue (ftruncate (getFD (fileHandle), (off_t) currentPosition));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if BEAST_PROBEASTR_LIVE_BUILD
|
||||
extern "C" const char* beast_getCurrentExecutablePath();
|
||||
#endif
|
||||
|
||||
File beast_getExecutableFile();
|
||||
File beast_getExecutableFile()
|
||||
{
|
||||
#if BEAST_PROBEASTR_LIVE_BUILD
|
||||
return File (beast_getCurrentExecutablePath());
|
||||
#elif BEAST_ANDROID
|
||||
return File (android.appFile);
|
||||
#else
|
||||
struct DLAddrReader
|
||||
{
|
||||
static String getFilename()
|
||||
{
|
||||
Dl_info exeInfo;
|
||||
dladdr ((void*) beast_getExecutableFile, &exeInfo);
|
||||
return CharPointer_UTF8 (exeInfo.dli_fname);
|
||||
}
|
||||
};
|
||||
|
||||
static String filename (DLAddrReader::getFilename());
|
||||
return File::getCurrentWorkingDirectory().getChildFile (filename);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // beast
|
||||
#endif
|
||||
@@ -1,372 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
#ifndef INVALID_FILE_ATTRIBUTES
|
||||
#define INVALID_FILE_ATTRIBUTES ((DWORD) -1)
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
namespace WindowsFileHelpers
|
||||
{
|
||||
static_assert (sizeof (ULARGE_INTEGER) == sizeof (FILETIME),
|
||||
"The FILETIME structure format has been modified.");
|
||||
|
||||
DWORD getAtts (const String& path)
|
||||
{
|
||||
return GetFileAttributes (path.toWideCharPointer());
|
||||
}
|
||||
|
||||
std::int64_t fileTimeToTime (const FILETIME* const ft)
|
||||
{
|
||||
return (std::int64_t) ((reinterpret_cast<const ULARGE_INTEGER*> (ft)->QuadPart - 116444736000000000LL) / 10000);
|
||||
}
|
||||
|
||||
FILETIME* timeToFileTime (const std::int64_t time, FILETIME* const ft) noexcept
|
||||
{
|
||||
if (time <= 0)
|
||||
return nullptr;
|
||||
|
||||
reinterpret_cast<ULARGE_INTEGER*> (ft)->QuadPart = (ULONGLONG) (time * 10000 + 116444736000000000LL);
|
||||
return ft;
|
||||
}
|
||||
|
||||
String getDriveFromPath (String path)
|
||||
{
|
||||
if (path.isNotEmpty() && path[1] == ':' && path[2] == 0)
|
||||
path << '\\';
|
||||
|
||||
const size_t numBytes = CharPointer_UTF16::getBytesRequiredFor (path.getCharPointer()) + 4;
|
||||
HeapBlock<WCHAR> pathCopy;
|
||||
pathCopy.calloc (numBytes, 1);
|
||||
path.copyToUTF16 (pathCopy, numBytes);
|
||||
|
||||
if (PathStripToRoot (pathCopy))
|
||||
path = static_cast <const WCHAR*> (pathCopy);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
unsigned int getWindowsDriveType (const String& path)
|
||||
{
|
||||
return GetDriveType (getDriveFromPath (path).toWideCharPointer());
|
||||
}
|
||||
|
||||
File getSpecialFolderPath (int type)
|
||||
{
|
||||
WCHAR path [MAX_PATH + 256];
|
||||
|
||||
if (SHGetSpecialFolderPath (0, path, type, FALSE))
|
||||
return File (String (path));
|
||||
|
||||
return File::nonexistent ();
|
||||
}
|
||||
|
||||
File getModuleFileName (HINSTANCE moduleHandle)
|
||||
{
|
||||
WCHAR dest [MAX_PATH + 256];
|
||||
dest[0] = 0;
|
||||
GetModuleFileName (moduleHandle, dest, (DWORD) numElementsInArray (dest));
|
||||
return File (String (dest));
|
||||
}
|
||||
|
||||
Result getResultForLastError()
|
||||
{
|
||||
TCHAR messageBuffer [256] = { 0 };
|
||||
|
||||
FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
nullptr, GetLastError(), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
messageBuffer, (DWORD) numElementsInArray (messageBuffer) - 1, nullptr);
|
||||
|
||||
return Result::fail (String (messageBuffer));
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
const beast_wchar File::separator = '\\';
|
||||
const String File::separatorString ("\\");
|
||||
|
||||
|
||||
//==============================================================================
|
||||
bool File::exists() const
|
||||
{
|
||||
return fullPath.isNotEmpty()
|
||||
&& WindowsFileHelpers::getAtts (fullPath) != INVALID_FILE_ATTRIBUTES;
|
||||
}
|
||||
|
||||
bool File::existsAsFile() const
|
||||
{
|
||||
return fullPath.isNotEmpty()
|
||||
&& (WindowsFileHelpers::getAtts (fullPath) & FILE_ATTRIBUTE_DIRECTORY) == 0;
|
||||
}
|
||||
|
||||
bool File::isDirectory() const
|
||||
{
|
||||
const DWORD attr = WindowsFileHelpers::getAtts (fullPath);
|
||||
return ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) && (attr != INVALID_FILE_ATTRIBUTES);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool File::deleteFile() const
|
||||
{
|
||||
if (! exists())
|
||||
return true;
|
||||
|
||||
return isDirectory() ? RemoveDirectory (fullPath.toWideCharPointer()) != 0
|
||||
: DeleteFile (fullPath.toWideCharPointer()) != 0;
|
||||
}
|
||||
|
||||
Result File::createDirectoryInternal (const String& fileName) const
|
||||
{
|
||||
return CreateDirectory (fileName.toWideCharPointer(), 0) ? Result::ok()
|
||||
: WindowsFileHelpers::getResultForLastError();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
std::int64_t beast_fileSetPosition (void* handle, std::int64_t pos)
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = pos;
|
||||
li.LowPart = SetFilePointer ((HANDLE) handle, (LONG) li.LowPart, &li.HighPart, FILE_BEGIN); // (returns -1 if it fails)
|
||||
return li.QuadPart;
|
||||
}
|
||||
|
||||
void FileInputStream::openHandle()
|
||||
{
|
||||
HANDLE h = CreateFile (file.getFullPathName().toWideCharPointer(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0);
|
||||
|
||||
if (h != INVALID_HANDLE_VALUE)
|
||||
fileHandle = (void*) h;
|
||||
else
|
||||
status = WindowsFileHelpers::getResultForLastError();
|
||||
}
|
||||
|
||||
void FileInputStream::closeHandle()
|
||||
{
|
||||
CloseHandle ((HANDLE) fileHandle);
|
||||
}
|
||||
|
||||
size_t FileInputStream::readInternal (void* buffer, size_t numBytes)
|
||||
{
|
||||
if (fileHandle != 0)
|
||||
{
|
||||
DWORD actualNum = 0;
|
||||
if (! ReadFile ((HANDLE) fileHandle, buffer, (DWORD) numBytes, &actualNum, 0))
|
||||
status = WindowsFileHelpers::getResultForLastError();
|
||||
|
||||
return (size_t) actualNum;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void FileOutputStream::openHandle()
|
||||
{
|
||||
HANDLE h = CreateFile (file.getFullPathName().toWideCharPointer(), GENERIC_WRITE, FILE_SHARE_READ, 0,
|
||||
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
|
||||
if (h != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = 0;
|
||||
li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_END);
|
||||
|
||||
if (li.LowPart != INVALID_SET_FILE_POINTER)
|
||||
{
|
||||
fileHandle = (void*) h;
|
||||
currentPosition = li.QuadPart;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
status = WindowsFileHelpers::getResultForLastError();
|
||||
}
|
||||
|
||||
void FileOutputStream::closeHandle()
|
||||
{
|
||||
CloseHandle ((HANDLE) fileHandle);
|
||||
}
|
||||
|
||||
std::ptrdiff_t FileOutputStream::writeInternal (const void* buffer, size_t numBytes)
|
||||
{
|
||||
if (fileHandle != nullptr)
|
||||
{
|
||||
DWORD actualNum = 0;
|
||||
if (! WriteFile ((HANDLE) fileHandle, buffer, (DWORD) numBytes, &actualNum, 0))
|
||||
status = WindowsFileHelpers::getResultForLastError();
|
||||
|
||||
return (std::ptrdiff_t) actualNum;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FileOutputStream::flushInternal()
|
||||
{
|
||||
if (fileHandle != nullptr)
|
||||
if (! FlushFileBuffers ((HANDLE) fileHandle))
|
||||
status = WindowsFileHelpers::getResultForLastError();
|
||||
}
|
||||
|
||||
Result FileOutputStream::truncate()
|
||||
{
|
||||
if (fileHandle == nullptr)
|
||||
return status;
|
||||
|
||||
flush();
|
||||
return SetEndOfFile ((HANDLE) fileHandle) ? Result::ok()
|
||||
: WindowsFileHelpers::getResultForLastError();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
std::int64_t File::getSize() const
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA attributes;
|
||||
|
||||
if (GetFileAttributesEx (fullPath.toWideCharPointer(), GetFileExInfoStandard, &attributes))
|
||||
return (((std::int64_t) attributes.nFileSizeHigh) << 32) | attributes.nFileSizeLow;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
File File::getSpecialLocation (const SpecialLocationType type)
|
||||
{
|
||||
int csidlType = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case userHomeDirectory: csidlType = CSIDL_PROFILE; break;
|
||||
case userDocumentsDirectory: csidlType = CSIDL_PERSONAL; break;
|
||||
case userDesktopDirectory: csidlType = CSIDL_DESKTOP; break;
|
||||
case userApplicationDataDirectory: csidlType = CSIDL_APPDATA; break;
|
||||
case commonApplicationDataDirectory: csidlType = CSIDL_COMMON_APPDATA; break;
|
||||
case commonDocumentsDirectory: csidlType = CSIDL_COMMON_DOCUMENTS; break;
|
||||
case globalApplicationsDirectory: csidlType = CSIDL_PROGRAM_FILES; break;
|
||||
case userMusicDirectory: csidlType = 0x0d; /*CSIDL_MYMUSIC*/ break;
|
||||
case userMoviesDirectory: csidlType = 0x0e; /*CSIDL_MYVIDEO*/ break;
|
||||
case userPicturesDirectory: csidlType = 0x27; /*CSIDL_MYPICTURES*/ break;
|
||||
|
||||
case tempDirectory:
|
||||
{
|
||||
WCHAR dest [2048];
|
||||
dest[0] = 0;
|
||||
GetTempPath ((DWORD) numElementsInArray (dest), dest);
|
||||
return File (String (dest));
|
||||
}
|
||||
|
||||
default:
|
||||
bassertfalse; // unknown type?
|
||||
return File::nonexistent ();
|
||||
}
|
||||
|
||||
return WindowsFileHelpers::getSpecialFolderPath (csidlType);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
File File::getCurrentWorkingDirectory()
|
||||
{
|
||||
WCHAR dest [MAX_PATH + 256];
|
||||
dest[0] = 0;
|
||||
GetCurrentDirectory ((DWORD) numElementsInArray (dest), dest);
|
||||
return File (String (dest));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class DirectoryIterator::NativeIterator::Pimpl
|
||||
{
|
||||
public:
|
||||
Pimpl (const File& directory, const String& wildCard)
|
||||
: directoryWithWildCard (File::addTrailingSeparator (directory.getFullPathName()) + wildCard),
|
||||
handle (INVALID_HANDLE_VALUE)
|
||||
{
|
||||
}
|
||||
|
||||
Pimpl (Pimpl const&) = delete;
|
||||
Pimpl& operator= (Pimpl const&) = delete;
|
||||
|
||||
~Pimpl()
|
||||
{
|
||||
if (handle != INVALID_HANDLE_VALUE)
|
||||
FindClose (handle);
|
||||
}
|
||||
|
||||
bool next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, std::int64_t* const fileSize,
|
||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
|
||||
{
|
||||
using namespace WindowsFileHelpers;
|
||||
WIN32_FIND_DATA findData;
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
handle = FindFirstFile (directoryWithWildCard.toWideCharPointer(), &findData);
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FindNextFile (handle, &findData) == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
filenameFound = findData.cFileName;
|
||||
|
||||
if (isDir != nullptr) *isDir = ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
|
||||
if (isHidden != nullptr) *isHidden = ((findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0);
|
||||
if (isReadOnly != nullptr) *isReadOnly = ((findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0);
|
||||
if (fileSize != nullptr) *fileSize = findData.nFileSizeLow + (((std::int64_t) findData.nFileSizeHigh) << 32);
|
||||
if (modTime != nullptr) *modTime = Time (fileTimeToTime (&findData.ftLastWriteTime));
|
||||
if (creationTime != nullptr) *creationTime = Time (fileTimeToTime (&findData.ftCreationTime));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
const String directoryWithWildCard;
|
||||
HANDLE handle;
|
||||
};
|
||||
|
||||
DirectoryIterator::NativeIterator::NativeIterator (const File& directory, const String& wildCard)
|
||||
: pimpl (new DirectoryIterator::NativeIterator::Pimpl (directory, wildCard))
|
||||
{
|
||||
}
|
||||
|
||||
DirectoryIterator::NativeIterator::~NativeIterator()
|
||||
{
|
||||
}
|
||||
|
||||
bool DirectoryIterator::NativeIterator::next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, std::int64_t* const fileSize,
|
||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
|
||||
{
|
||||
return pimpl->next (filenameFound, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly);
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -29,12 +29,6 @@ void outputDebugString (std::string const& text)
|
||||
OutputDebugStringA ((text + "\n").c_str ());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool beast_isRunningUnderDebugger()
|
||||
{
|
||||
return IsDebuggerPresent() != FALSE;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
std::string getComputerName()
|
||||
{
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
void* getUser32Function (const char* functionName)
|
||||
{
|
||||
HMODULE module = GetModuleHandleA ("user32.dll");
|
||||
bassert (module != 0);
|
||||
return (void*) GetProcAddress (module, functionName);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if ! BEAST_USE_INTRINSICS
|
||||
// In newer compilers, the inline versions of these are used (in beast_Atomic.h), but in
|
||||
// older ones we have to actually call the ops as win32 functions..
|
||||
long beast_InterlockedExchange (volatile long* a, long b) noexcept { return InterlockedExchange (a, b); }
|
||||
long beast_InterlockedIncrement (volatile long* a) noexcept { return InterlockedIncrement (a); }
|
||||
long beast_InterlockedDecrement (volatile long* a) noexcept { return InterlockedDecrement (a); }
|
||||
long beast_InterlockedExchangeAdd (volatile long* a, long b) noexcept { return InterlockedExchangeAdd (a, b); }
|
||||
long beast_InterlockedCompareExchange (volatile long* a, long b, long c) noexcept { return InterlockedCompareExchange (a, b, c); }
|
||||
|
||||
__int64 beast_InterlockedCompareExchange64 (volatile __int64* value, __int64 newValue, __int64 valueToCompare) noexcept
|
||||
{
|
||||
bassertfalse; // This operation isn't available in old MS compiler versions!
|
||||
|
||||
__int64 oldValue = *value;
|
||||
if (oldValue == valueToCompare)
|
||||
*value = newValue;
|
||||
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
|
||||
|
||||
CriticalSection::CriticalSection() noexcept
|
||||
{
|
||||
// (just to check the MS haven't changed this structure and broken things...)
|
||||
#if BEAST_VC7_OR_EARLIER
|
||||
static_assert (sizeof (CRITICAL_SECTION) <= 24,
|
||||
"The size of the CRITICAL_SECTION structure is less not what we expected.");
|
||||
#else
|
||||
static_assert (sizeof (CRITICAL_SECTION) <= sizeof (CriticalSection::section),
|
||||
"The size of the CRITICAL_SECTION structure is less not what we expected.");
|
||||
#endif
|
||||
|
||||
InitializeCriticalSection ((CRITICAL_SECTION*) section);
|
||||
}
|
||||
|
||||
CriticalSection::~CriticalSection() noexcept { DeleteCriticalSection ((CRITICAL_SECTION*) section); }
|
||||
void CriticalSection::enter() const noexcept { EnterCriticalSection ((CRITICAL_SECTION*) section); }
|
||||
bool CriticalSection::tryEnter() const noexcept { return TryEnterCriticalSection ((CRITICAL_SECTION*) section) != FALSE; }
|
||||
void CriticalSection::exit() const noexcept { LeaveCriticalSection ((CRITICAL_SECTION*) section); }
|
||||
|
||||
} // beast
|
||||
@@ -1,69 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_STREAMS_INPUTSOURCE_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_STREAMS_INPUTSOURCE_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A lightweight object that can create a stream to read some kind of resource.
|
||||
|
||||
This may be used to refer to a file, or some other kind of source, allowing a
|
||||
caller to create an input stream that can read from it when required.
|
||||
*/
|
||||
class InputSource
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
InputSource() noexcept {}
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~InputSource() {}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a new InputStream to read this item.
|
||||
|
||||
@returns an inputstream that the caller will delete, or nullptr if
|
||||
the filename isn't found.
|
||||
*/
|
||||
virtual InputStream* createInputStream() = 0;
|
||||
|
||||
/** Returns a new InputStream to read an item, relative.
|
||||
|
||||
@param relatedItemPath the relative pathname of the resource that is required
|
||||
@returns an inputstream that the caller will delete, or nullptr if
|
||||
the item isn't found.
|
||||
*/
|
||||
virtual InputStream* createInputStreamFor (const String& relatedItemPath) = 0;
|
||||
|
||||
/** Returns a hash code that uniquely represents this item.
|
||||
*/
|
||||
virtual std::int64_t hashCode() const = 0;
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_INPUTSOURCE_H_INCLUDED
|
||||
@@ -1,329 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
std::int64_t InputStream::getNumBytesRemaining()
|
||||
{
|
||||
std::int64_t len = getTotalLength();
|
||||
|
||||
if (len >= 0)
|
||||
len -= getPosition();
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
char InputStream::readByte()
|
||||
{
|
||||
char temp = 0;
|
||||
read (&temp, 1);
|
||||
return temp;
|
||||
}
|
||||
|
||||
bool InputStream::readBool()
|
||||
{
|
||||
return readByte() != 0;
|
||||
}
|
||||
|
||||
short InputStream::readShort()
|
||||
{
|
||||
char temp[2];
|
||||
|
||||
if (read (temp, 2) == 2)
|
||||
return (short) ByteOrder::littleEndianShort (temp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
short InputStream::readShortBigEndian()
|
||||
{
|
||||
char temp[2];
|
||||
|
||||
if (read (temp, 2) == 2)
|
||||
return (short) ByteOrder::bigEndianShort (temp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int InputStream::readInt()
|
||||
{
|
||||
static_assert (sizeof (int) == 4,
|
||||
"The size of an integer must be exactly 4 bytes");
|
||||
|
||||
char temp[4];
|
||||
|
||||
if (read (temp, 4) == 4)
|
||||
return (int) ByteOrder::littleEndianInt (temp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::int32_t InputStream::readInt32()
|
||||
{
|
||||
char temp[4];
|
||||
|
||||
if (read (temp, 4) == 4)
|
||||
return (std::int32_t) ByteOrder::littleEndianInt (temp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int InputStream::readIntBigEndian()
|
||||
{
|
||||
char temp[4];
|
||||
|
||||
if (read (temp, 4) == 4)
|
||||
return (int) ByteOrder::bigEndianInt (temp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::int32_t InputStream::readInt32BigEndian()
|
||||
{
|
||||
char temp[4];
|
||||
|
||||
if (read (temp, 4) == 4)
|
||||
return (std::int32_t) ByteOrder::bigEndianInt (temp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int InputStream::readCompressedInt()
|
||||
{
|
||||
const std::uint8_t sizeByte = (std::uint8_t) readByte();
|
||||
if (sizeByte == 0)
|
||||
return 0;
|
||||
|
||||
const int numBytes = (sizeByte & 0x7f);
|
||||
if (numBytes > 4)
|
||||
{
|
||||
bassertfalse; // trying to read corrupt data - this method must only be used
|
||||
// to read data that was written by OutputStream::writeCompressedInt()
|
||||
return 0;
|
||||
}
|
||||
|
||||
char bytes[4] = { 0, 0, 0, 0 };
|
||||
if (read (bytes, numBytes) != numBytes)
|
||||
return 0;
|
||||
|
||||
const int num = (int) ByteOrder::littleEndianInt (bytes);
|
||||
return (sizeByte >> 7) ? -num : num;
|
||||
}
|
||||
|
||||
std::int64_t InputStream::readInt64()
|
||||
{
|
||||
union { std::uint8_t asBytes[8]; std::uint64_t asInt64; } n;
|
||||
|
||||
if (read (n.asBytes, 8) == 8)
|
||||
return (std::int64_t) ByteOrder::swapIfBigEndian (n.asInt64);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::int64_t InputStream::readInt64BigEndian()
|
||||
{
|
||||
union { std::uint8_t asBytes[8]; std::uint64_t asInt64; } n;
|
||||
|
||||
if (read (n.asBytes, 8) == 8)
|
||||
return (std::int64_t) ByteOrder::swapIfLittleEndian (n.asInt64);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
float InputStream::readFloat()
|
||||
{
|
||||
// the union below relies on these types being the same size...
|
||||
static_assert (sizeof (std::int32_t) == sizeof (float),
|
||||
"The size of a float must be equal to the size of an std::int32_t");
|
||||
|
||||
union { std::int32_t asInt; float asFloat; } n;
|
||||
n.asInt = (std::int32_t) readInt();
|
||||
return n.asFloat;
|
||||
}
|
||||
|
||||
float InputStream::readFloatBigEndian()
|
||||
{
|
||||
union { std::int32_t asInt; float asFloat; } n;
|
||||
n.asInt = (std::int32_t) readIntBigEndian();
|
||||
return n.asFloat;
|
||||
}
|
||||
|
||||
double InputStream::readDouble()
|
||||
{
|
||||
union { std::int64_t asInt; double asDouble; } n;
|
||||
n.asInt = readInt64();
|
||||
return n.asDouble;
|
||||
}
|
||||
|
||||
double InputStream::readDoubleBigEndian()
|
||||
{
|
||||
union { std::int64_t asInt; double asDouble; } n;
|
||||
n.asInt = readInt64BigEndian();
|
||||
return n.asDouble;
|
||||
}
|
||||
|
||||
String InputStream::readString()
|
||||
{
|
||||
MemoryBlock buffer (256);
|
||||
char* data = static_cast<char*> (buffer.getData());
|
||||
size_t i = 0;
|
||||
|
||||
while ((data[i] = readByte()) != 0)
|
||||
{
|
||||
if (++i >= buffer.getSize())
|
||||
{
|
||||
buffer.setSize (buffer.getSize() + 512);
|
||||
data = static_cast<char*> (buffer.getData());
|
||||
}
|
||||
}
|
||||
|
||||
return String (CharPointer_UTF8 (data),
|
||||
CharPointer_UTF8 (data + i));
|
||||
}
|
||||
|
||||
String InputStream::readNextLine()
|
||||
{
|
||||
MemoryBlock buffer (256);
|
||||
char* data = static_cast<char*> (buffer.getData());
|
||||
size_t i = 0;
|
||||
|
||||
while ((data[i] = readByte()) != 0)
|
||||
{
|
||||
if (data[i] == '\n')
|
||||
break;
|
||||
|
||||
if (data[i] == '\r')
|
||||
{
|
||||
const std::int64_t lastPos = getPosition();
|
||||
|
||||
if (readByte() != '\n')
|
||||
setPosition (lastPos);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (++i >= buffer.getSize())
|
||||
{
|
||||
buffer.setSize (buffer.getSize() + 512);
|
||||
data = static_cast<char*> (buffer.getData());
|
||||
}
|
||||
}
|
||||
|
||||
return String::fromUTF8 (data, (int) i);
|
||||
}
|
||||
|
||||
int InputStream::readIntoMemoryBlock (MemoryBlock& block, std::ptrdiff_t numBytes)
|
||||
{
|
||||
MemoryOutputStream mo (block, true);
|
||||
return mo.writeFromInputStream (*this, numBytes);
|
||||
}
|
||||
|
||||
String InputStream::readEntireStreamAsString()
|
||||
{
|
||||
MemoryOutputStream mo;
|
||||
mo << *this;
|
||||
return mo.toString();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void InputStream::skipNextBytes (std::int64_t numBytesToSkip)
|
||||
{
|
||||
if (numBytesToSkip > 0)
|
||||
{
|
||||
const int skipBufferSize = (int) std::min (numBytesToSkip, (std::int64_t) 16384);
|
||||
HeapBlock<char> temp ((size_t) skipBufferSize);
|
||||
|
||||
while (numBytesToSkip > 0 && ! isExhausted())
|
||||
numBytesToSkip -= read (temp, (int) std::min (numBytesToSkip, (std::int64_t) skipBufferSize));
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Unfortunately, putting these in the header causes duplicate
|
||||
// definition linker errors, even with the inline keyword!
|
||||
|
||||
template <>
|
||||
char InputStream::readType <char> () { return readByte (); }
|
||||
|
||||
template <>
|
||||
short InputStream::readType <short> () { return readShort (); }
|
||||
|
||||
template <>
|
||||
std::int32_t InputStream::readType <std::int32_t> () { return readInt32 (); }
|
||||
|
||||
template <>
|
||||
std::int64_t InputStream::readType <std::int64_t> () { return readInt64 (); }
|
||||
|
||||
template <>
|
||||
unsigned char InputStream::readType <unsigned char> () { return static_cast <unsigned char> (readByte ()); }
|
||||
|
||||
template <>
|
||||
unsigned short InputStream::readType <unsigned short> () { return static_cast <unsigned short> (readShort ()); }
|
||||
|
||||
template <>
|
||||
std::uint32_t InputStream::readType <std::uint32_t> () { return static_cast <std::uint32_t> (readInt32 ()); }
|
||||
|
||||
template <>
|
||||
std::uint64_t InputStream::readType <std::uint64_t> () { return static_cast <std::uint64_t> (readInt64 ()); }
|
||||
|
||||
template <>
|
||||
float InputStream::readType <float> () { return readFloat (); }
|
||||
|
||||
template <>
|
||||
double InputStream::readType <double> () { return readDouble (); }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <>
|
||||
char InputStream::readTypeBigEndian <char> () { return readByte (); }
|
||||
|
||||
template <>
|
||||
short InputStream::readTypeBigEndian <short> () { return readShortBigEndian (); }
|
||||
|
||||
template <>
|
||||
std::int32_t InputStream::readTypeBigEndian <std::int32_t> () { return readInt32BigEndian (); }
|
||||
|
||||
template <>
|
||||
std::int64_t InputStream::readTypeBigEndian <std::int64_t> () { return readInt64BigEndian (); }
|
||||
|
||||
template <>
|
||||
unsigned char InputStream::readTypeBigEndian <unsigned char> () { return static_cast <unsigned char> (readByte ()); }
|
||||
|
||||
template <>
|
||||
unsigned short InputStream::readTypeBigEndian <unsigned short> () { return static_cast <unsigned short> (readShortBigEndian ()); }
|
||||
|
||||
template <>
|
||||
std::uint32_t InputStream::readTypeBigEndian <std::uint32_t> () { return static_cast <std::uint32_t> (readInt32BigEndian ()); }
|
||||
|
||||
template <>
|
||||
std::uint64_t InputStream::readTypeBigEndian <std::uint64_t> () { return static_cast <std::uint64_t> (readInt64BigEndian ()); }
|
||||
|
||||
template <>
|
||||
float InputStream::readTypeBigEndian <float> () { return readFloatBigEndian (); }
|
||||
|
||||
template <>
|
||||
double InputStream::readTypeBigEndian <double> () { return readDoubleBigEndian (); }
|
||||
|
||||
} // beast
|
||||
@@ -1,360 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_STREAMS_INPUTSTREAM_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_STREAMS_INPUTSTREAM_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
class MemoryBlock;
|
||||
|
||||
//==============================================================================
|
||||
/** The base class for streams that read data.
|
||||
|
||||
Input and output streams are used throughout the library - subclasses can override
|
||||
some or all of the virtual functions to implement their behaviour.
|
||||
|
||||
@see OutputStream, FileInputStream
|
||||
*/
|
||||
class InputStream
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~InputStream() {}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the total number of bytes available for reading in this stream.
|
||||
|
||||
Note that this is the number of bytes available from the start of the
|
||||
stream, not from the current position.
|
||||
|
||||
If the size of the stream isn't actually known, this will return -1.
|
||||
|
||||
@see getNumBytesRemaining
|
||||
*/
|
||||
virtual std::int64_t getTotalLength() = 0;
|
||||
|
||||
/** Returns the number of bytes available for reading, or a negative value if
|
||||
the remaining length is not known.
|
||||
@see getTotalLength
|
||||
*/
|
||||
std::int64_t getNumBytesRemaining();
|
||||
|
||||
/** Returns true if the stream has no more data to read. */
|
||||
virtual bool isExhausted() = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** Reads some data from the stream into a memory buffer.
|
||||
|
||||
This is the only read method that subclasses actually need to implement, as the
|
||||
InputStream base class implements the other read methods in terms of this one (although
|
||||
it's often more efficient for subclasses to implement them directly).
|
||||
|
||||
@param destBuffer the destination buffer for the data. This must not be null.
|
||||
@param maxBytesToRead the maximum number of bytes to read - make sure the
|
||||
memory block passed in is big enough to contain this
|
||||
many bytes. This value must not be negative.
|
||||
|
||||
@returns the actual number of bytes that were read, which may be less than
|
||||
maxBytesToRead if the stream is exhausted before it gets that far
|
||||
*/
|
||||
virtual int read (void* destBuffer, int maxBytesToRead) = 0;
|
||||
|
||||
/** Reads a byte from the stream.
|
||||
|
||||
If the stream is exhausted, this will return zero.
|
||||
|
||||
@see OutputStream::writeByte
|
||||
*/
|
||||
virtual char readByte();
|
||||
|
||||
/** Reads a boolean from the stream.
|
||||
|
||||
The bool is encoded as a single byte - non-zero for true, 0 for false.
|
||||
|
||||
If the stream is exhausted, this will return false.
|
||||
|
||||
@see OutputStream::writeBool
|
||||
*/
|
||||
virtual bool readBool();
|
||||
|
||||
/** Reads two bytes from the stream as a little-endian 16-bit value.
|
||||
|
||||
If the next two bytes read are byte1 and byte2, this returns
|
||||
(byte1 | (byte2 << 8)).
|
||||
|
||||
If the stream is exhausted partway through reading the bytes, this will return zero.
|
||||
|
||||
@see OutputStream::writeShort, readShortBigEndian
|
||||
*/
|
||||
virtual short readShort();
|
||||
|
||||
// VFALCO TODO Implement these functions
|
||||
//virtual std::int16_t readInt16 ();
|
||||
//virtual std::uint16_t readUInt16 ();
|
||||
|
||||
/** Reads two bytes from the stream as a little-endian 16-bit value.
|
||||
|
||||
If the next two bytes read are byte1 and byte2, this returns (byte1 | (byte2 << 8)).
|
||||
|
||||
If the stream is exhausted partway through reading the bytes, this will return zero.
|
||||
|
||||
@see OutputStream::writeShortBigEndian, readShort
|
||||
*/
|
||||
virtual short readShortBigEndian();
|
||||
|
||||
/** Reads four bytes from the stream as a little-endian 32-bit value.
|
||||
|
||||
If the next four bytes are byte1 to byte4, this returns
|
||||
(byte1 | (byte2 << 8) | (byte3 << 16) | (byte4 << 24)).
|
||||
|
||||
If the stream is exhausted partway through reading the bytes, this will return zero.
|
||||
|
||||
@see OutputStream::writeInt, readIntBigEndian
|
||||
*/
|
||||
virtual std::int32_t readInt32();
|
||||
|
||||
// VFALCO TODO Implement these functions
|
||||
//virtual std::int16_t readInt16BigEndian ();
|
||||
//virtual std::uint16_t readUInt16BigEndian ();
|
||||
|
||||
// DEPRECATED, assumes sizeof(int) == 4!
|
||||
virtual int readInt();
|
||||
|
||||
/** Reads four bytes from the stream as a big-endian 32-bit value.
|
||||
|
||||
If the next four bytes are byte1 to byte4, this returns
|
||||
(byte4 | (byte3 << 8) | (byte2 << 16) | (byte1 << 24)).
|
||||
|
||||
If the stream is exhausted partway through reading the bytes, this will return zero.
|
||||
|
||||
@see OutputStream::writeIntBigEndian, readInt
|
||||
*/
|
||||
virtual std::int32_t readInt32BigEndian();
|
||||
|
||||
// DEPRECATED, assumes sizeof(int) == 4!
|
||||
virtual int readIntBigEndian();
|
||||
|
||||
/** Reads eight bytes from the stream as a little-endian 64-bit value.
|
||||
|
||||
If the next eight bytes are byte1 to byte8, this returns
|
||||
(byte1 | (byte2 << 8) | (byte3 << 16) | (byte4 << 24) | (byte5 << 32) | (byte6 << 40) | (byte7 << 48) | (byte8 << 56)).
|
||||
|
||||
If the stream is exhausted partway through reading the bytes, this will return zero.
|
||||
|
||||
@see OutputStream::writeInt64, readInt64BigEndian
|
||||
*/
|
||||
virtual std::int64_t readInt64();
|
||||
|
||||
/** Reads eight bytes from the stream as a big-endian 64-bit value.
|
||||
|
||||
If the next eight bytes are byte1 to byte8, this returns
|
||||
(byte8 | (byte7 << 8) | (byte6 << 16) | (byte5 << 24) | (byte4 << 32) | (byte3 << 40) | (byte2 << 48) | (byte1 << 56)).
|
||||
|
||||
If the stream is exhausted partway through reading the bytes, this will return zero.
|
||||
|
||||
@see OutputStream::writeInt64BigEndian, readInt64
|
||||
*/
|
||||
virtual std::int64_t readInt64BigEndian();
|
||||
|
||||
/** Reads four bytes as a 32-bit floating point value.
|
||||
|
||||
The raw 32-bit encoding of the float is read from the stream as a little-endian int.
|
||||
|
||||
If the stream is exhausted partway through reading the bytes, this will return zero.
|
||||
|
||||
@see OutputStream::writeFloat, readDouble
|
||||
*/
|
||||
virtual float readFloat();
|
||||
|
||||
/** Reads four bytes as a 32-bit floating point value.
|
||||
|
||||
The raw 32-bit encoding of the float is read from the stream as a big-endian int.
|
||||
|
||||
If the stream is exhausted partway through reading the bytes, this will return zero.
|
||||
|
||||
@see OutputStream::writeFloatBigEndian, readDoubleBigEndian
|
||||
*/
|
||||
virtual float readFloatBigEndian();
|
||||
|
||||
/** Reads eight bytes as a 64-bit floating point value.
|
||||
|
||||
The raw 64-bit encoding of the double is read from the stream as a little-endian std::int64_t.
|
||||
|
||||
If the stream is exhausted partway through reading the bytes, this will return zero.
|
||||
|
||||
@see OutputStream::writeDouble, readFloat
|
||||
*/
|
||||
virtual double readDouble();
|
||||
|
||||
/** Reads eight bytes as a 64-bit floating point value.
|
||||
|
||||
The raw 64-bit encoding of the double is read from the stream as a big-endian std::int64_t.
|
||||
|
||||
If the stream is exhausted partway through reading the bytes, this will return zero.
|
||||
|
||||
@see OutputStream::writeDoubleBigEndian, readFloatBigEndian
|
||||
*/
|
||||
virtual double readDoubleBigEndian();
|
||||
|
||||
/** Reads an encoded 32-bit number from the stream using a space-saving compressed format.
|
||||
|
||||
For small values, this is more space-efficient than using readInt() and OutputStream::writeInt()
|
||||
|
||||
The format used is: number of significant bytes + up to 4 bytes in little-endian order.
|
||||
|
||||
@see OutputStream::writeCompressedInt()
|
||||
*/
|
||||
virtual int readCompressedInt();
|
||||
|
||||
/** Reads a type using a template specialization.
|
||||
|
||||
This is useful when doing template meta-programming.
|
||||
*/
|
||||
template <class T>
|
||||
T readType ();
|
||||
|
||||
/** Reads a type using a template specialization.
|
||||
|
||||
The variable is passed as a parameter so that the template type
|
||||
can be deduced. The return value indicates whether or not there
|
||||
was sufficient data in the stream to read the value.
|
||||
|
||||
*/
|
||||
template <class T>
|
||||
bool readTypeInto (T* p)
|
||||
{
|
||||
if (getNumBytesRemaining () >= sizeof (T))
|
||||
{
|
||||
*p = readType <T> ();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Reads a type from a big endian stream using a template specialization.
|
||||
|
||||
The raw encoding of the type is read from the stream as a big-endian value
|
||||
where applicable.
|
||||
|
||||
This is useful when doing template meta-programming.
|
||||
*/
|
||||
template <class T>
|
||||
T readTypeBigEndian ();
|
||||
|
||||
/** Reads a type using a template specialization.
|
||||
|
||||
The variable is passed as a parameter so that the template type
|
||||
can be deduced. The return value indicates whether or not there
|
||||
was sufficient data in the stream to read the value.
|
||||
*/
|
||||
template <class T>
|
||||
bool readTypeBigEndianInto (T* p)
|
||||
{
|
||||
if (getNumBytesRemaining () >= sizeof (T))
|
||||
{
|
||||
*p = readTypeBigEndian <T> ();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Reads a UTF-8 string from the stream, up to the next linefeed or carriage return.
|
||||
|
||||
This will read up to the next "\n" or "\r\n" or end-of-stream.
|
||||
|
||||
After this call, the stream's position will be left pointing to the next character
|
||||
following the line-feed, but the linefeeds aren't included in the string that
|
||||
is returned.
|
||||
*/
|
||||
virtual String readNextLine();
|
||||
|
||||
/** Reads a zero-terminated UTF-8 string from the stream.
|
||||
|
||||
This will read characters from the stream until it hits a null character
|
||||
or end-of-stream.
|
||||
|
||||
@see OutputStream::writeString, readEntireStreamAsString
|
||||
*/
|
||||
virtual String readString();
|
||||
|
||||
/** Tries to read the whole stream and turn it into a string.
|
||||
|
||||
This will read from the stream's current position until the end-of-stream.
|
||||
It can read from either UTF-16 or UTF-8 formats.
|
||||
*/
|
||||
virtual String readEntireStreamAsString();
|
||||
|
||||
/** Reads from the stream and appends the data to a MemoryBlock.
|
||||
|
||||
@param destBlock the block to append the data onto
|
||||
@param maxNumBytesToRead if this is a positive value, it sets a limit to the number
|
||||
of bytes that will be read - if it's negative, data
|
||||
will be read until the stream is exhausted.
|
||||
@returns the number of bytes that were added to the memory block
|
||||
*/
|
||||
virtual int readIntoMemoryBlock (MemoryBlock& destBlock,
|
||||
std::ptrdiff_t maxNumBytesToRead = -1);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the offset of the next byte that will be read from the stream.
|
||||
|
||||
@see setPosition
|
||||
*/
|
||||
virtual std::int64_t getPosition() = 0;
|
||||
|
||||
/** Tries to move the current read position of the stream.
|
||||
|
||||
The position is an absolute number of bytes from the stream's start.
|
||||
|
||||
Some streams might not be able to do this, in which case they should do
|
||||
nothing and return false. Others might be able to manage it by resetting
|
||||
themselves and skipping to the correct position, although this is
|
||||
obviously a bit slow.
|
||||
|
||||
@returns true if the stream manages to reposition itself correctly
|
||||
@see getPosition
|
||||
*/
|
||||
virtual bool setPosition (std::int64_t newPosition) = 0;
|
||||
|
||||
/** Reads and discards a number of bytes from the stream.
|
||||
|
||||
Some input streams might implement this efficiently, but the base
|
||||
class will just keep reading data until the requisite number of bytes
|
||||
have been done.
|
||||
*/
|
||||
virtual void skipNextBytes (std::int64_t numBytesToSkip);
|
||||
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
InputStream() = default;
|
||||
InputStream (InputStream const&) = delete;
|
||||
InputStream& operator= (InputStream const&) = delete;
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -1,216 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
MemoryOutputStream::MemoryOutputStream (const size_t initialSize)
|
||||
: blockToUse (&internalBlock), externalData (nullptr),
|
||||
position (0), size (0), availableSize (0)
|
||||
{
|
||||
internalBlock.setSize (initialSize, false);
|
||||
}
|
||||
|
||||
MemoryOutputStream::MemoryOutputStream (MemoryBlock& memoryBlockToWriteTo,
|
||||
const bool appendToExistingBlockContent)
|
||||
: blockToUse (&memoryBlockToWriteTo), externalData (nullptr),
|
||||
position (0), size (0), availableSize (0)
|
||||
{
|
||||
if (appendToExistingBlockContent)
|
||||
position = size = memoryBlockToWriteTo.getSize();
|
||||
}
|
||||
|
||||
MemoryOutputStream::MemoryOutputStream (void* destBuffer, size_t destBufferSize)
|
||||
: blockToUse (nullptr), externalData (destBuffer),
|
||||
position (0), size (0), availableSize (destBufferSize)
|
||||
{
|
||||
bassert (externalData != nullptr); // This must be a valid pointer.
|
||||
}
|
||||
|
||||
MemoryOutputStream::~MemoryOutputStream()
|
||||
{
|
||||
trimExternalBlockSize();
|
||||
}
|
||||
|
||||
void MemoryOutputStream::flush()
|
||||
{
|
||||
trimExternalBlockSize();
|
||||
}
|
||||
|
||||
void MemoryOutputStream::trimExternalBlockSize()
|
||||
{
|
||||
if (blockToUse != &internalBlock && blockToUse != nullptr)
|
||||
blockToUse->setSize (size, false);
|
||||
}
|
||||
|
||||
void MemoryOutputStream::preallocate (const size_t bytesToPreallocate)
|
||||
{
|
||||
if (blockToUse != nullptr)
|
||||
blockToUse->ensureSize (bytesToPreallocate + 1);
|
||||
}
|
||||
|
||||
void MemoryOutputStream::reset() noexcept
|
||||
{
|
||||
position = 0;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
char* MemoryOutputStream::prepareToWrite (size_t numBytes)
|
||||
{
|
||||
bassert ((std::ptrdiff_t) numBytes >= 0);
|
||||
size_t storageNeeded = position + numBytes;
|
||||
|
||||
char* data;
|
||||
|
||||
if (blockToUse != nullptr)
|
||||
{
|
||||
if (storageNeeded >= blockToUse->getSize())
|
||||
blockToUse->ensureSize ((storageNeeded + std::min (storageNeeded / 2, (size_t) (1024 * 1024)) + 32) & ~31u);
|
||||
|
||||
data = static_cast <char*> (blockToUse->getData());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (storageNeeded > availableSize)
|
||||
return nullptr;
|
||||
|
||||
data = static_cast <char*> (externalData);
|
||||
}
|
||||
|
||||
char* const writePointer = data + position;
|
||||
position += numBytes;
|
||||
size = std::max (size, position);
|
||||
return writePointer;
|
||||
}
|
||||
|
||||
bool MemoryOutputStream::write (const void* const buffer, size_t howMany)
|
||||
{
|
||||
bassert (buffer != nullptr);
|
||||
|
||||
if (howMany == 0)
|
||||
return true;
|
||||
|
||||
if (char* dest = prepareToWrite (howMany))
|
||||
{
|
||||
memcpy (dest, buffer, howMany);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MemoryOutputStream::writeRepeatedByte (std::uint8_t byte, size_t howMany)
|
||||
{
|
||||
if (howMany == 0)
|
||||
return true;
|
||||
|
||||
if (char* dest = prepareToWrite (howMany))
|
||||
{
|
||||
memset (dest, byte, howMany);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MemoryOutputStream::appendUTF8Char (beast_wchar c)
|
||||
{
|
||||
if (char* dest = prepareToWrite (CharPointer_UTF8::getBytesRequiredFor (c)))
|
||||
{
|
||||
CharPointer_UTF8 (dest).write (c);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
MemoryBlock MemoryOutputStream::getMemoryBlock() const
|
||||
{
|
||||
return MemoryBlock (getData(), getDataSize());
|
||||
}
|
||||
|
||||
const void* MemoryOutputStream::getData() const noexcept
|
||||
{
|
||||
if (blockToUse == nullptr)
|
||||
return externalData;
|
||||
|
||||
if (blockToUse->getSize() > size)
|
||||
static_cast <char*> (blockToUse->getData()) [size] = 0;
|
||||
|
||||
return blockToUse->getData();
|
||||
}
|
||||
|
||||
bool MemoryOutputStream::setPosition (std::int64_t newPosition)
|
||||
{
|
||||
if (newPosition <= (std::int64_t) size)
|
||||
{
|
||||
// ok to seek backwards
|
||||
position = blimit ((size_t) 0, size, (size_t) newPosition);
|
||||
return true;
|
||||
}
|
||||
|
||||
// can't move beyond the end of the stream..
|
||||
return false;
|
||||
}
|
||||
|
||||
int MemoryOutputStream::writeFromInputStream (InputStream& source, std::int64_t maxNumBytesToWrite)
|
||||
{
|
||||
// before writing from an input, see if we can preallocate to make it more efficient..
|
||||
std::int64_t availableData = source.getTotalLength() - source.getPosition();
|
||||
|
||||
if (availableData > 0)
|
||||
{
|
||||
if (maxNumBytesToWrite > availableData)
|
||||
maxNumBytesToWrite = availableData;
|
||||
|
||||
if (blockToUse != nullptr)
|
||||
preallocate (blockToUse->getSize() + (size_t) maxNumBytesToWrite);
|
||||
}
|
||||
|
||||
return OutputStream::writeFromInputStream (source, maxNumBytesToWrite);
|
||||
}
|
||||
|
||||
String MemoryOutputStream::toUTF8() const
|
||||
{
|
||||
const char* const d = static_cast <const char*> (getData());
|
||||
return String (CharPointer_UTF8 (d), CharPointer_UTF8 (d + getDataSize()));
|
||||
}
|
||||
|
||||
String MemoryOutputStream::toString() const
|
||||
{
|
||||
return String::createStringFromData (getData(), (int) getDataSize());
|
||||
}
|
||||
|
||||
OutputStream& operator<< (OutputStream& stream, const MemoryOutputStream& streamToRead)
|
||||
{
|
||||
const size_t dataSize = streamToRead.getDataSize();
|
||||
|
||||
if (dataSize > 0)
|
||||
stream.write (streamToRead.getData(), dataSize);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -1,144 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_STREAMS_MEMORYOUTPUTSTREAM_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_STREAMS_MEMORYOUTPUTSTREAM_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Writes data to an internal memory buffer, which grows as required.
|
||||
|
||||
The data that was written into the stream can then be accessed later as
|
||||
a contiguous block of memory.
|
||||
*/
|
||||
//==============================================================================
|
||||
/**
|
||||
Writes data to an internal memory buffer, which grows as required.
|
||||
|
||||
The data that was written into the stream can then be accessed later as
|
||||
a contiguous block of memory.
|
||||
*/
|
||||
class MemoryOutputStream
|
||||
: public OutputStream
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty memory stream, ready to be written into.
|
||||
@param initialSize the intial amount of capacity to allocate for writing into
|
||||
*/
|
||||
MemoryOutputStream (size_t initialSize = 256);
|
||||
|
||||
/** Creates a memory stream for writing into into a pre-existing MemoryBlock object.
|
||||
|
||||
Note that the destination block will always be larger than the amount of data
|
||||
that has been written to the stream, because the MemoryOutputStream keeps some
|
||||
spare capactity at its end. To trim the block's size down to fit the actual
|
||||
data, call flush(), or delete the MemoryOutputStream.
|
||||
|
||||
@param memoryBlockToWriteTo the block into which new data will be written.
|
||||
@param appendToExistingBlockContent if this is true, the contents of the block will be
|
||||
kept, and new data will be appended to it. If false,
|
||||
the block will be cleared before use
|
||||
*/
|
||||
MemoryOutputStream (MemoryBlock& memoryBlockToWriteTo,
|
||||
bool appendToExistingBlockContent);
|
||||
|
||||
/** Creates a MemoryOutputStream that will write into a user-supplied, fixed-size
|
||||
block of memory.
|
||||
|
||||
When using this mode, the stream will write directly into this memory area until
|
||||
it's full, at which point write operations will fail.
|
||||
*/
|
||||
MemoryOutputStream (void* destBuffer, size_t destBufferSize);
|
||||
|
||||
/** Destructor.
|
||||
This will free any data that was written to it.
|
||||
*/
|
||||
~MemoryOutputStream();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a pointer to the data that has been written to the stream.
|
||||
@see getDataSize
|
||||
*/
|
||||
const void* getData() const noexcept;
|
||||
|
||||
/** Returns the number of bytes of data that have been written to the stream.
|
||||
@see getData
|
||||
*/
|
||||
size_t getDataSize() const noexcept { return size; }
|
||||
|
||||
/** Resets the stream, clearing any data that has been written to it so far. */
|
||||
void reset() noexcept;
|
||||
|
||||
/** Increases the internal storage capacity to be able to contain at least the specified
|
||||
amount of data without needing to be resized.
|
||||
*/
|
||||
void preallocate (size_t bytesToPreallocate);
|
||||
|
||||
/** Appends the utf-8 bytes for a unicode character */
|
||||
bool appendUTF8Char (beast_wchar character);
|
||||
|
||||
/** Returns a String created from the (UTF8) data that has been written to the stream. */
|
||||
String toUTF8() const;
|
||||
|
||||
/** Attempts to detect the encoding of the data and convert it to a string.
|
||||
@see String::createStringFromData
|
||||
*/
|
||||
String toString() const;
|
||||
|
||||
/** Returns a copy of the stream's data as a memory block. */
|
||||
MemoryBlock getMemoryBlock() const;
|
||||
|
||||
//==============================================================================
|
||||
/** If the stream is writing to a user-supplied MemoryBlock, this will trim any excess
|
||||
capacity off the block, so that its length matches the amount of actual data that
|
||||
has been written so far.
|
||||
*/
|
||||
void flush() override;
|
||||
|
||||
bool write (const void*, size_t) override;
|
||||
std::int64_t getPosition() override { return position; }
|
||||
bool setPosition (std::int64_t) override;
|
||||
int writeFromInputStream (InputStream&, std::int64_t maxNumBytesToWrite) override;
|
||||
bool writeRepeatedByte (std::uint8_t byte, size_t numTimesToRepeat) override;
|
||||
|
||||
private:
|
||||
void trimExternalBlockSize();
|
||||
char* prepareToWrite (size_t);
|
||||
|
||||
//==============================================================================
|
||||
MemoryBlock* const blockToUse;
|
||||
MemoryBlock internalBlock;
|
||||
void* externalData;
|
||||
size_t position, size, availableSize;
|
||||
};
|
||||
|
||||
/** Copies all the data that has been written to a MemoryOutputStream into another stream. */
|
||||
OutputStream& operator<< (OutputStream& stream, const MemoryOutputStream& streamToRead);
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -1,444 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
#if BEAST_DEBUG
|
||||
|
||||
struct DanglingStreamChecker
|
||||
{
|
||||
DanglingStreamChecker() {}
|
||||
|
||||
~DanglingStreamChecker()
|
||||
{
|
||||
/*
|
||||
It's always a bad idea to leak any object, but if you're leaking output
|
||||
streams, then there's a good chance that you're failing to flush a file
|
||||
to disk properly, which could result in corrupted data and other similar
|
||||
nastiness..
|
||||
*/
|
||||
bassert (activeStreams.size() == 0);
|
||||
}
|
||||
|
||||
Array<void*, CriticalSection> activeStreams;
|
||||
};
|
||||
|
||||
static DanglingStreamChecker danglingStreamChecker;
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
OutputStream::OutputStream()
|
||||
: newLineString (NewLine::getDefault())
|
||||
{
|
||||
#if BEAST_DEBUG
|
||||
danglingStreamChecker.activeStreams.add (this);
|
||||
#endif
|
||||
}
|
||||
|
||||
OutputStream::~OutputStream()
|
||||
{
|
||||
#if BEAST_DEBUG
|
||||
danglingStreamChecker.activeStreams.removeFirstMatchingValue (this);
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool OutputStream::writeBool (const bool b)
|
||||
{
|
||||
return writeByte (b ? (char) 1
|
||||
: (char) 0);
|
||||
}
|
||||
|
||||
bool OutputStream::writeByte (char byte)
|
||||
{
|
||||
return write (&byte, 1);
|
||||
}
|
||||
|
||||
bool OutputStream::writeRepeatedByte (std::uint8_t byte, size_t numTimesToRepeat)
|
||||
{
|
||||
for (size_t i = 0; i < numTimesToRepeat; ++i)
|
||||
if (! writeByte ((char) byte))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OutputStream::writeShort (short value)
|
||||
{
|
||||
const unsigned short v = ByteOrder::swapIfBigEndian ((unsigned short) value);
|
||||
return write (&v, 2);
|
||||
}
|
||||
|
||||
bool OutputStream::writeShortBigEndian (short value)
|
||||
{
|
||||
const unsigned short v = ByteOrder::swapIfLittleEndian ((unsigned short) value);
|
||||
return write (&v, 2);
|
||||
}
|
||||
|
||||
bool OutputStream::writeInt32 (std::int32_t value)
|
||||
{
|
||||
static_assert (sizeof (std::int32_t) == 4,
|
||||
"The size of an integer must be exactly 4 bytes.");
|
||||
|
||||
const unsigned int v = ByteOrder::swapIfBigEndian ((std::uint32_t) value);
|
||||
return write (&v, 4);
|
||||
}
|
||||
|
||||
bool OutputStream::writeInt (int value)
|
||||
{
|
||||
static_assert (sizeof (int) == 4,
|
||||
"The size of an integer must be exactly 4 bytes.");
|
||||
|
||||
const unsigned int v = ByteOrder::swapIfBigEndian ((unsigned int) value);
|
||||
return write (&v, 4);
|
||||
}
|
||||
|
||||
bool OutputStream::writeInt32BigEndian (int value)
|
||||
{
|
||||
static_assert (sizeof (std::int32_t) == 4,
|
||||
"The size of an integer must be exactly 4 bytes.");
|
||||
const std::uint32_t v = ByteOrder::swapIfLittleEndian ((std::uint32_t) value);
|
||||
return write (&v, 4);
|
||||
}
|
||||
|
||||
bool OutputStream::writeIntBigEndian (int value)
|
||||
{
|
||||
static_assert (sizeof (int) == 4,
|
||||
"The size of an integer must be exactly 4 bytes.");
|
||||
const unsigned int v = ByteOrder::swapIfLittleEndian ((unsigned int) value);
|
||||
return write (&v, 4);
|
||||
}
|
||||
|
||||
bool OutputStream::writeCompressedInt (int value)
|
||||
{
|
||||
unsigned int un = (value < 0) ? (unsigned int) -value
|
||||
: (unsigned int) value;
|
||||
|
||||
std::uint8_t data[5];
|
||||
int num = 0;
|
||||
|
||||
while (un > 0)
|
||||
{
|
||||
data[++num] = (std::uint8_t) un;
|
||||
un >>= 8;
|
||||
}
|
||||
|
||||
data[0] = (std::uint8_t) num;
|
||||
|
||||
if (value < 0)
|
||||
data[0] |= 0x80;
|
||||
|
||||
return write (data, (size_t) num + 1);
|
||||
}
|
||||
|
||||
bool OutputStream::writeInt64 (std::int64_t value)
|
||||
{
|
||||
const std::uint64_t v = ByteOrder::swapIfBigEndian ((std::uint64_t) value);
|
||||
return write (&v, 8);
|
||||
}
|
||||
|
||||
bool OutputStream::writeInt64BigEndian (std::int64_t value)
|
||||
{
|
||||
const std::uint64_t v = ByteOrder::swapIfLittleEndian ((std::uint64_t) value);
|
||||
return write (&v, 8);
|
||||
}
|
||||
|
||||
bool OutputStream::writeFloat (float value)
|
||||
{
|
||||
union { int asInt; float asFloat; } n;
|
||||
n.asFloat = value;
|
||||
return writeInt (n.asInt);
|
||||
}
|
||||
|
||||
bool OutputStream::writeFloatBigEndian (float value)
|
||||
{
|
||||
union { int asInt; float asFloat; } n;
|
||||
n.asFloat = value;
|
||||
return writeIntBigEndian (n.asInt);
|
||||
}
|
||||
|
||||
bool OutputStream::writeDouble (double value)
|
||||
{
|
||||
union { std::int64_t asInt; double asDouble; } n;
|
||||
n.asDouble = value;
|
||||
return writeInt64 (n.asInt);
|
||||
}
|
||||
|
||||
bool OutputStream::writeDoubleBigEndian (double value)
|
||||
{
|
||||
union { std::int64_t asInt; double asDouble; } n;
|
||||
n.asDouble = value;
|
||||
return writeInt64BigEndian (n.asInt);
|
||||
}
|
||||
|
||||
bool OutputStream::writeString (const String& text)
|
||||
{
|
||||
// (This avoids using toUTF8() to prevent the memory bloat that it would leave behind
|
||||
// if lots of large, persistent strings were to be written to streams).
|
||||
const size_t numBytes = text.getNumBytesAsUTF8() + 1;
|
||||
HeapBlock<char> temp (numBytes);
|
||||
text.copyToUTF8 (temp, numBytes);
|
||||
return write (temp, numBytes);
|
||||
}
|
||||
|
||||
bool OutputStream::writeText (const String& text, const bool asUTF16,
|
||||
const bool writeUTF16ByteOrderMark)
|
||||
{
|
||||
if (asUTF16)
|
||||
{
|
||||
if (writeUTF16ByteOrderMark)
|
||||
write ("\x0ff\x0fe", 2);
|
||||
|
||||
String::CharPointerType src (text.getCharPointer());
|
||||
bool lastCharWasReturn = false;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const beast_wchar c = src.getAndAdvance();
|
||||
|
||||
if (c == 0)
|
||||
break;
|
||||
|
||||
if (c == '\n' && ! lastCharWasReturn)
|
||||
writeShort ((short) '\r');
|
||||
|
||||
lastCharWasReturn = (c == L'\r');
|
||||
|
||||
if (! writeShort ((short) c))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* src = text.toUTF8();
|
||||
const char* t = src;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*t == '\n')
|
||||
{
|
||||
if (t > src)
|
||||
if (! write (src, (size_t) (t - src)))
|
||||
return false;
|
||||
|
||||
if (! write ("\r\n", 2))
|
||||
return false;
|
||||
|
||||
src = t + 1;
|
||||
}
|
||||
else if (*t == '\r')
|
||||
{
|
||||
if (t[1] == '\n')
|
||||
++t;
|
||||
}
|
||||
else if (*t == 0)
|
||||
{
|
||||
if (t > src)
|
||||
if (! write (src, (size_t) (t - src)))
|
||||
return false;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
++t;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int OutputStream::writeFromInputStream (InputStream& source, std::int64_t numBytesToWrite)
|
||||
{
|
||||
if (numBytesToWrite < 0)
|
||||
numBytesToWrite = std::numeric_limits<std::int64_t>::max();
|
||||
|
||||
int numWritten = 0;
|
||||
|
||||
while (numBytesToWrite > 0)
|
||||
{
|
||||
char buffer [8192];
|
||||
const int num = source.read (buffer, (int) std::min (numBytesToWrite, (std::int64_t) sizeof (buffer)));
|
||||
|
||||
if (num <= 0)
|
||||
break;
|
||||
|
||||
write (buffer, (size_t) num);
|
||||
|
||||
numBytesToWrite -= num;
|
||||
numWritten += num;
|
||||
}
|
||||
|
||||
return numWritten;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void OutputStream::setNewLineString (const String& newLineString_)
|
||||
{
|
||||
newLineString = newLineString_;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
OutputStream& operator<< (OutputStream& stream, const int number)
|
||||
{
|
||||
return stream << String (number);
|
||||
}
|
||||
|
||||
OutputStream& operator<< (OutputStream& stream, const std::int64_t number)
|
||||
{
|
||||
return stream << String (number);
|
||||
}
|
||||
|
||||
OutputStream& operator<< (OutputStream& stream, const double number)
|
||||
{
|
||||
return stream << String (number);
|
||||
}
|
||||
|
||||
OutputStream& operator<< (OutputStream& stream, const char character)
|
||||
{
|
||||
stream.writeByte (character);
|
||||
return stream;
|
||||
}
|
||||
|
||||
OutputStream& operator<< (OutputStream& stream, const char* const text)
|
||||
{
|
||||
stream.write (text, strlen (text));
|
||||
return stream;
|
||||
}
|
||||
|
||||
OutputStream& operator<< (OutputStream& stream, const MemoryBlock& data)
|
||||
{
|
||||
if (data.getSize() > 0)
|
||||
stream.write (data.getData(), data.getSize());
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
OutputStream& operator<< (OutputStream& stream, const File& fileToRead)
|
||||
{
|
||||
FileInputStream in (fileToRead);
|
||||
|
||||
if (in.openedOk())
|
||||
return stream << in;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
OutputStream& operator<< (OutputStream& stream, InputStream& streamToRead)
|
||||
{
|
||||
stream.writeFromInputStream (streamToRead, -1);
|
||||
return stream;
|
||||
}
|
||||
|
||||
OutputStream& operator<< (OutputStream& stream, const NewLine&)
|
||||
{
|
||||
return stream << stream.getNewLineString();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Unfortunately, putting these in the header causes duplicate
|
||||
// definition linker errors, even with the inline keyword!
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeType <char> (char v) { return writeByte (v); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeType <short> (short v) { return writeShort (v); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeType <std::int32_t> (std::int32_t v) { return writeInt32 (v); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeType <std::int64_t> (std::int64_t v) { return writeInt64 (v); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeType <unsigned char> (unsigned char v) { return writeByte (static_cast <char> (v)); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeType <unsigned short> (unsigned short v) { return writeShort (static_cast <short> (v)); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeType <std::uint32_t> (std::uint32_t v) { return writeInt32 (static_cast <std::int32_t> (v)); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeType <std::uint64_t> (std::uint64_t v) { return writeInt64 (static_cast <std::int64_t> (v)); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeType <float> (float v) { return writeFloat (v); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeType <double> (double v) { return writeDouble (v); }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeTypeBigEndian <char> (char v) { return writeByte (v); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeTypeBigEndian <short> (short v) { return writeShortBigEndian (v); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeTypeBigEndian <std::int32_t> (std::int32_t v) { return writeInt32BigEndian (v); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeTypeBigEndian <std::int64_t> (std::int64_t v) { return writeInt64BigEndian (v); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeTypeBigEndian <unsigned char> (unsigned char v) { return writeByte (static_cast <char> (v)); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeTypeBigEndian <unsigned short> (unsigned short v) { return writeShortBigEndian (static_cast <short> (v)); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeTypeBigEndian <std::uint32_t> (std::uint32_t v) { return writeInt32BigEndian (static_cast <std::int32_t> (v)); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeTypeBigEndian <std::uint64_t> (std::uint64_t v) { return writeInt64BigEndian (static_cast <std::int64_t> (v)); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeTypeBigEndian <float> (float v) { return writeFloatBigEndian (v); }
|
||||
|
||||
template <>
|
||||
bool OutputStream::writeTypeBigEndian <double> (double v) { return writeDoubleBigEndian (v); }
|
||||
|
||||
OutputStream& operator<< (OutputStream& stream, const String& text)
|
||||
{
|
||||
const size_t numBytes = text.getNumBytesAsUTF8();
|
||||
|
||||
#if (BEAST_STRING_UTF_TYPE == 8)
|
||||
stream.write (text.getCharPointer().getAddress(), numBytes);
|
||||
#else
|
||||
// (This avoids using toUTF8() to prevent the memory bloat that it would leave behind
|
||||
// if lots of large, persistent strings were to be written to streams).
|
||||
HeapBlock<char> temp (numBytes + 1);
|
||||
CharPointer_UTF8 (temp).writeAll (text.getCharPointer());
|
||||
stream.write (temp, numBytes);
|
||||
#endif
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -1,307 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_STREAMS_OUTPUTSTREAM_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_STREAMS_OUTPUTSTREAM_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
class InputStream;
|
||||
class MemoryBlock;
|
||||
class File;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
The base class for streams that write data to some kind of destination.
|
||||
|
||||
Input and output streams are used throughout the library - subclasses can override
|
||||
some or all of the virtual functions to implement their behaviour.
|
||||
|
||||
@see InputStream, MemoryOutputStream, FileOutputStream
|
||||
*/
|
||||
class OutputStream
|
||||
{
|
||||
protected:
|
||||
//==============================================================================
|
||||
OutputStream();
|
||||
|
||||
OutputStream (OutputStream const&) = delete;
|
||||
OutputStream& operator= (OutputStream const&) = delete;
|
||||
|
||||
public:
|
||||
/** Destructor.
|
||||
|
||||
Some subclasses might want to do things like call flush() during their
|
||||
destructors.
|
||||
*/
|
||||
virtual ~OutputStream();
|
||||
|
||||
//==============================================================================
|
||||
/** If the stream is using a buffer, this will ensure it gets written
|
||||
out to the destination. */
|
||||
virtual void flush() = 0;
|
||||
|
||||
/** Tries to move the stream's output position.
|
||||
|
||||
Not all streams will be able to seek to a new position - this will return
|
||||
false if it fails to work.
|
||||
|
||||
@see getPosition
|
||||
*/
|
||||
virtual bool setPosition (std::int64_t newPosition) = 0;
|
||||
|
||||
/** Returns the stream's current position.
|
||||
|
||||
@see setPosition
|
||||
*/
|
||||
virtual std::int64_t getPosition() = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** Writes a block of data to the stream.
|
||||
|
||||
When creating a subclass of OutputStream, this is the only write method
|
||||
that needs to be overloaded - the base class has methods for writing other
|
||||
types of data which use this to do the work.
|
||||
|
||||
@param dataToWrite the target buffer to receive the data. This must not be null.
|
||||
@param numberOfBytes the number of bytes to write.
|
||||
@returns false if the write operation fails for some reason
|
||||
*/
|
||||
virtual bool write (const void* dataToWrite,
|
||||
size_t numberOfBytes) = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** Writes a single byte to the stream.
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readByte
|
||||
*/
|
||||
virtual bool writeByte (char byte);
|
||||
|
||||
/** Writes a boolean to the stream as a single byte.
|
||||
This is encoded as a binary byte (not as text) with a value of 1 or 0.
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readBool
|
||||
*/
|
||||
virtual bool writeBool (bool boolValue);
|
||||
|
||||
/** Writes a 16-bit integer to the stream in a little-endian byte order.
|
||||
This will write two bytes to the stream: (value & 0xff), then (value >> 8).
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readShort
|
||||
*/
|
||||
virtual bool writeShort (short value);
|
||||
|
||||
/** Writes a 16-bit integer to the stream in a big-endian byte order.
|
||||
This will write two bytes to the stream: (value >> 8), then (value & 0xff).
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readShortBigEndian
|
||||
*/
|
||||
virtual bool writeShortBigEndian (short value);
|
||||
|
||||
/** Writes a 32-bit integer to the stream in a little-endian byte order.
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readInt
|
||||
*/
|
||||
virtual bool writeInt32 (std::int32_t value);
|
||||
|
||||
// DEPRECATED, assumes sizeof (int) == 4!
|
||||
virtual bool writeInt (int value);
|
||||
|
||||
/** Writes a 32-bit integer to the stream in a big-endian byte order.
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readIntBigEndian
|
||||
*/
|
||||
virtual bool writeInt32BigEndian (std::int32_t value);
|
||||
|
||||
// DEPRECATED, assumes sizeof (int) == 4!
|
||||
virtual bool writeIntBigEndian (int value);
|
||||
|
||||
/** Writes a 64-bit integer to the stream in a little-endian byte order.
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readInt64
|
||||
*/
|
||||
virtual bool writeInt64 (std::int64_t value);
|
||||
|
||||
/** Writes a 64-bit integer to the stream in a big-endian byte order.
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readInt64BigEndian
|
||||
*/
|
||||
virtual bool writeInt64BigEndian (std::int64_t value);
|
||||
|
||||
/** Writes a 32-bit floating point value to the stream in a binary format.
|
||||
The binary 32-bit encoding of the float is written as a little-endian int.
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readFloat
|
||||
*/
|
||||
virtual bool writeFloat (float value);
|
||||
|
||||
/** Writes a 32-bit floating point value to the stream in a binary format.
|
||||
The binary 32-bit encoding of the float is written as a big-endian int.
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readFloatBigEndian
|
||||
*/
|
||||
virtual bool writeFloatBigEndian (float value);
|
||||
|
||||
/** Writes a 64-bit floating point value to the stream in a binary format.
|
||||
The eight raw bytes of the double value are written out as a little-endian 64-bit int.
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readDouble
|
||||
*/
|
||||
virtual bool writeDouble (double value);
|
||||
|
||||
/** Writes a 64-bit floating point value to the stream in a binary format.
|
||||
The eight raw bytes of the double value are written out as a big-endian 64-bit int.
|
||||
@see InputStream::readDoubleBigEndian
|
||||
@returns false if the write operation fails for some reason
|
||||
*/
|
||||
virtual bool writeDoubleBigEndian (double value);
|
||||
|
||||
/** Write a type using a template specialization.
|
||||
|
||||
This is useful when doing template meta-programming.
|
||||
*/
|
||||
template <class T>
|
||||
bool writeType (T value);
|
||||
|
||||
/** Write a type using a template specialization.
|
||||
|
||||
The raw encoding of the type is written to the stream as a big-endian value
|
||||
where applicable.
|
||||
|
||||
This is useful when doing template meta-programming.
|
||||
*/
|
||||
template <class T>
|
||||
bool writeTypeBigEndian (T value);
|
||||
|
||||
/** Writes a byte to the output stream a given number of times.
|
||||
@returns false if the write operation fails for some reason
|
||||
*/
|
||||
virtual bool writeRepeatedByte (std::uint8_t byte, size_t numTimesToRepeat);
|
||||
|
||||
/** Writes a condensed binary encoding of a 32-bit integer.
|
||||
|
||||
If you're storing a lot of integers which are unlikely to have very large values,
|
||||
this can save a lot of space, because values under 0xff will only take up 2 bytes,
|
||||
under 0xffff only 3 bytes, etc.
|
||||
|
||||
The format used is: number of significant bytes + up to 4 bytes in little-endian order.
|
||||
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readCompressedInt
|
||||
*/
|
||||
virtual bool writeCompressedInt (int value);
|
||||
|
||||
/** Stores a string in the stream in a binary format.
|
||||
|
||||
This isn't the method to use if you're trying to append text to the end of a
|
||||
text-file! It's intended for storing a string so that it can be retrieved later
|
||||
by InputStream::readString().
|
||||
|
||||
It writes the string to the stream as UTF8, including the null termination character.
|
||||
|
||||
For appending text to a file, instead use writeText, or operator<<
|
||||
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readString, writeText, operator<<
|
||||
*/
|
||||
virtual bool writeString (const String& text);
|
||||
|
||||
/** Writes a string of text to the stream.
|
||||
|
||||
It can either write the text as UTF-8 or UTF-16, and can also add the UTF-16 byte-order-mark
|
||||
bytes (0xff, 0xfe) to indicate the endianness (these should only be used at the start
|
||||
of a file).
|
||||
|
||||
The method also replaces '\\n' characters in the text with '\\r\\n'.
|
||||
@returns false if the write operation fails for some reason
|
||||
*/
|
||||
virtual bool writeText (const String& text,
|
||||
bool asUTF16,
|
||||
bool writeUTF16ByteOrderMark);
|
||||
|
||||
/** Reads data from an input stream and writes it to this stream.
|
||||
|
||||
@param source the stream to read from
|
||||
@param maxNumBytesToWrite the number of bytes to read from the stream (if this is
|
||||
less than zero, it will keep reading until the input
|
||||
is exhausted)
|
||||
@returns the number of bytes written
|
||||
*/
|
||||
virtual int writeFromInputStream (InputStream& source, std::int64_t maxNumBytesToWrite);
|
||||
|
||||
//==============================================================================
|
||||
/** Sets the string that will be written to the stream when the writeNewLine()
|
||||
method is called.
|
||||
By default this will be set the the value of NewLine::getDefault().
|
||||
*/
|
||||
void setNewLineString (const String& newLineString);
|
||||
|
||||
/** Returns the current new-line string that was set by setNewLineString(). */
|
||||
const String& getNewLineString() const noexcept { return newLineString; }
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
String newLineString;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Writes a number to a stream as 8-bit characters in the default system encoding. */
|
||||
OutputStream& operator<< (OutputStream& stream, int number);
|
||||
|
||||
/** Writes a number to a stream as 8-bit characters in the default system encoding. */
|
||||
OutputStream& operator<< (OutputStream& stream, std::int64_t number);
|
||||
|
||||
/** Writes a number to a stream as 8-bit characters in the default system encoding. */
|
||||
OutputStream& operator<< (OutputStream& stream, double number);
|
||||
|
||||
/** Writes a character to a stream. */
|
||||
OutputStream& operator<< (OutputStream& stream, char character);
|
||||
|
||||
/** Writes a null-terminated text string to a stream. */
|
||||
OutputStream& operator<< (OutputStream& stream, const char* text);
|
||||
|
||||
/** Writes a block of data from a MemoryBlock to a stream. */
|
||||
OutputStream& operator<< (OutputStream& stream, const MemoryBlock& data);
|
||||
|
||||
/** Writes the contents of a file to a stream. */
|
||||
OutputStream& operator<< (OutputStream& stream, const File& fileToRead);
|
||||
|
||||
/** Writes the complete contents of an input stream to an output stream. */
|
||||
OutputStream& operator<< (OutputStream& stream, InputStream& streamToRead);
|
||||
|
||||
/** Writes a new-line to a stream.
|
||||
You can use the predefined symbol 'newLine' to invoke this, e.g.
|
||||
@code
|
||||
myOutputStream << "Hello World" << newLine << newLine;
|
||||
@endcode
|
||||
@see OutputStream::setNewLineString
|
||||
*/
|
||||
OutputStream& operator<< (OutputStream& stream, const NewLine&);
|
||||
|
||||
/** Writes a string to an OutputStream as UTF8. */
|
||||
OutputStream& operator<< (OutputStream& stream, const String& stringToWrite);
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -49,7 +49,7 @@ getStackBacktrace()
|
||||
std::vector <std::string> result;
|
||||
|
||||
#if BEAST_ANDROID || BEAST_MINGW || BEAST_BSD
|
||||
bassertfalse; // sorry, not implemented yet!
|
||||
assert(false); // sorry, not implemented yet!
|
||||
|
||||
#elif BEAST_WINDOWS
|
||||
HANDLE process = GetCurrentProcess();
|
||||
|
||||
@@ -1,517 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
StringArray::StringArray() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
StringArray::StringArray (const StringArray& other)
|
||||
: strings (other.strings)
|
||||
{
|
||||
}
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
StringArray::StringArray (StringArray&& other) noexcept
|
||||
: strings (static_cast <Array <String>&&> (other.strings))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
StringArray::StringArray (const String& firstValue)
|
||||
{
|
||||
strings.add (firstValue);
|
||||
}
|
||||
|
||||
namespace StringArrayHelpers
|
||||
{
|
||||
template <typename CharType>
|
||||
void addArray (Array<String>& dest, const CharType* const* strings)
|
||||
{
|
||||
if (strings != nullptr)
|
||||
while (*strings != nullptr)
|
||||
dest.add (*strings++);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void addArray (Array<String>& dest, const Type* const strings, const int numberOfStrings)
|
||||
{
|
||||
for (int i = 0; i < numberOfStrings; ++i)
|
||||
dest.add (strings [i]);
|
||||
}
|
||||
}
|
||||
|
||||
StringArray::StringArray (const String* initialStrings, int numberOfStrings)
|
||||
{
|
||||
StringArrayHelpers::addArray (strings, initialStrings, numberOfStrings);
|
||||
}
|
||||
|
||||
StringArray::StringArray (const char* const* const initialStrings)
|
||||
{
|
||||
StringArrayHelpers::addArray (strings, initialStrings);
|
||||
}
|
||||
|
||||
StringArray::StringArray (const char* const* const initialStrings, const int numberOfStrings)
|
||||
{
|
||||
StringArrayHelpers::addArray (strings, initialStrings, numberOfStrings);
|
||||
}
|
||||
|
||||
StringArray::StringArray (const wchar_t* const* const initialStrings)
|
||||
{
|
||||
StringArrayHelpers::addArray (strings, initialStrings);
|
||||
}
|
||||
|
||||
StringArray::StringArray (const wchar_t* const* const initialStrings, const int numberOfStrings)
|
||||
{
|
||||
StringArrayHelpers::addArray (strings, initialStrings, numberOfStrings);
|
||||
}
|
||||
|
||||
StringArray& StringArray::operator= (const StringArray& other)
|
||||
{
|
||||
strings = other.strings;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
StringArray& StringArray::operator= (StringArray&& other) noexcept
|
||||
{
|
||||
strings = static_cast <Array<String>&&> (other.strings);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
StringArray::~StringArray()
|
||||
{
|
||||
}
|
||||
|
||||
bool StringArray::operator== (const StringArray& other) const noexcept
|
||||
{
|
||||
if (other.size() != size())
|
||||
return false;
|
||||
|
||||
for (int i = size(); --i >= 0;)
|
||||
if (other.strings.getReference(i) != strings.getReference(i))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StringArray::operator!= (const StringArray& other) const noexcept
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
void StringArray::swapWith (StringArray& other) noexcept
|
||||
{
|
||||
strings.swapWith (other.strings);
|
||||
}
|
||||
|
||||
void StringArray::clear()
|
||||
{
|
||||
strings.clear();
|
||||
}
|
||||
|
||||
const String& StringArray::operator[] (const int index) const noexcept
|
||||
{
|
||||
if (isPositiveAndBelow (index, strings.size()))
|
||||
return strings.getReference (index);
|
||||
|
||||
return String::empty;
|
||||
}
|
||||
|
||||
String& StringArray::getReference (const int index) noexcept
|
||||
{
|
||||
bassert (isPositiveAndBelow (index, strings.size()));
|
||||
return strings.getReference (index);
|
||||
}
|
||||
|
||||
void StringArray::add (const String& newString)
|
||||
{
|
||||
strings.add (newString);
|
||||
}
|
||||
|
||||
void StringArray::insert (const int index, const String& newString)
|
||||
{
|
||||
strings.insert (index, newString);
|
||||
}
|
||||
|
||||
void StringArray::addIfNotAlreadyThere (const String& newString, const bool ignoreCase)
|
||||
{
|
||||
if (! contains (newString, ignoreCase))
|
||||
add (newString);
|
||||
}
|
||||
|
||||
void StringArray::addArray (const StringArray& otherArray, int startIndex, int numElementsToAdd)
|
||||
{
|
||||
if (startIndex < 0)
|
||||
{
|
||||
bassertfalse;
|
||||
startIndex = 0;
|
||||
}
|
||||
|
||||
if (numElementsToAdd < 0 || startIndex + numElementsToAdd > otherArray.size())
|
||||
numElementsToAdd = otherArray.size() - startIndex;
|
||||
|
||||
while (--numElementsToAdd >= 0)
|
||||
strings.add (otherArray.strings.getReference (startIndex++));
|
||||
}
|
||||
|
||||
void StringArray::set (const int index, const String& newString)
|
||||
{
|
||||
strings.set (index, newString);
|
||||
}
|
||||
|
||||
bool StringArray::contains (const String& stringToLookFor, const bool ignoreCase) const
|
||||
{
|
||||
if (ignoreCase)
|
||||
{
|
||||
for (int i = size(); --i >= 0;)
|
||||
if (strings.getReference(i).equalsIgnoreCase (stringToLookFor))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = size(); --i >= 0;)
|
||||
if (stringToLookFor == strings.getReference(i))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int StringArray::indexOf (const String& stringToLookFor, const bool ignoreCase, int i) const
|
||||
{
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
|
||||
const int numElements = size();
|
||||
|
||||
if (ignoreCase)
|
||||
{
|
||||
while (i < numElements)
|
||||
{
|
||||
if (strings.getReference(i).equalsIgnoreCase (stringToLookFor))
|
||||
return i;
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (i < numElements)
|
||||
{
|
||||
if (stringToLookFor == strings.getReference (i))
|
||||
return i;
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void StringArray::remove (const int index)
|
||||
{
|
||||
strings.remove (index);
|
||||
}
|
||||
|
||||
void StringArray::removeString (const String& stringToRemove,
|
||||
const bool ignoreCase)
|
||||
{
|
||||
if (ignoreCase)
|
||||
{
|
||||
for (int i = size(); --i >= 0;)
|
||||
if (strings.getReference(i).equalsIgnoreCase (stringToRemove))
|
||||
strings.remove (i);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = size(); --i >= 0;)
|
||||
if (stringToRemove == strings.getReference (i))
|
||||
strings.remove (i);
|
||||
}
|
||||
}
|
||||
|
||||
void StringArray::removeRange (int startIndex, int numberToRemove)
|
||||
{
|
||||
strings.removeRange (startIndex, numberToRemove);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void StringArray::removeEmptyStrings (const bool removeWhitespaceStrings)
|
||||
{
|
||||
if (removeWhitespaceStrings)
|
||||
{
|
||||
for (int i = size(); --i >= 0;)
|
||||
if (! strings.getReference(i).containsNonWhitespaceChars())
|
||||
strings.remove (i);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = size(); --i >= 0;)
|
||||
if (strings.getReference(i).isEmpty())
|
||||
strings.remove (i);
|
||||
}
|
||||
}
|
||||
|
||||
void StringArray::trim()
|
||||
{
|
||||
for (int i = size(); --i >= 0;)
|
||||
{
|
||||
String& s = strings.getReference(i);
|
||||
s = s.trim();
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct InternalStringArrayComparator_CaseSensitive
|
||||
{
|
||||
static int compareElements (String& first, String& second) { return first.compare (second); }
|
||||
};
|
||||
|
||||
struct InternalStringArrayComparator_CaseInsensitive
|
||||
{
|
||||
static int compareElements (String& first, String& second) { return first.compareIgnoreCase (second); }
|
||||
};
|
||||
|
||||
void StringArray::sort (const bool ignoreCase)
|
||||
{
|
||||
if (ignoreCase)
|
||||
{
|
||||
InternalStringArrayComparator_CaseInsensitive comp;
|
||||
strings.sort (comp);
|
||||
}
|
||||
else
|
||||
{
|
||||
InternalStringArrayComparator_CaseSensitive comp;
|
||||
strings.sort (comp);
|
||||
}
|
||||
}
|
||||
|
||||
void StringArray::move (const int currentIndex, int newIndex) noexcept
|
||||
{
|
||||
strings.move (currentIndex, newIndex);
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
String StringArray::joinIntoString (const String& separator, int start, int numberToJoin) const
|
||||
{
|
||||
const int last = (numberToJoin < 0) ? size()
|
||||
: std::min (size(), start + numberToJoin);
|
||||
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
|
||||
if (start >= last)
|
||||
return String::empty;
|
||||
|
||||
if (start == last - 1)
|
||||
return strings.getReference (start);
|
||||
|
||||
const size_t separatorBytes = separator.getCharPointer().sizeInBytes() - sizeof (String::CharPointerType::CharType);
|
||||
size_t bytesNeeded = separatorBytes * (size_t) (last - start - 1);
|
||||
|
||||
for (int i = start; i < last; ++i)
|
||||
bytesNeeded += strings.getReference(i).getCharPointer().sizeInBytes() - sizeof (String::CharPointerType::CharType);
|
||||
|
||||
String result;
|
||||
result.preallocateBytes (bytesNeeded);
|
||||
|
||||
String::CharPointerType dest (result.getCharPointer());
|
||||
|
||||
while (start < last)
|
||||
{
|
||||
const String& s = strings.getReference (start);
|
||||
|
||||
if (! s.isEmpty())
|
||||
dest.writeAll (s.getCharPointer());
|
||||
|
||||
if (++start < last && separatorBytes > 0)
|
||||
dest.writeAll (separator.getCharPointer());
|
||||
}
|
||||
|
||||
dest.writeNull();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int StringArray::addTokens (const String& text, const bool preserveQuotedStrings)
|
||||
{
|
||||
return addTokens (text, " \n\r\t", preserveQuotedStrings ? "\"" : "");
|
||||
}
|
||||
|
||||
int StringArray::addTokens (const String& text, const String& breakCharacters, const String& quoteCharacters)
|
||||
{
|
||||
int num = 0;
|
||||
String::CharPointerType t (text.getCharPointer());
|
||||
|
||||
if (! t.isEmpty())
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
String::CharPointerType tokenEnd (CharacterFunctions::findEndOfToken (t,
|
||||
breakCharacters.getCharPointer(),
|
||||
quoteCharacters.getCharPointer()));
|
||||
strings.add (String (t, tokenEnd));
|
||||
++num;
|
||||
|
||||
if (tokenEnd.isEmpty())
|
||||
break;
|
||||
|
||||
t = ++tokenEnd;
|
||||
}
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int StringArray::addLines (const String& sourceText)
|
||||
{
|
||||
int numLines = 0;
|
||||
String::CharPointerType text (sourceText.getCharPointer());
|
||||
bool finished = text.isEmpty();
|
||||
|
||||
while (! finished)
|
||||
{
|
||||
for (String::CharPointerType startOfLine (text);;)
|
||||
{
|
||||
const String::CharPointerType endOfLine (text);
|
||||
|
||||
switch (text.getAndAdvance())
|
||||
{
|
||||
case 0: finished = true; break;
|
||||
case '\n': break;
|
||||
case '\r': if (*text == '\n') ++text; break;
|
||||
default: continue;
|
||||
}
|
||||
|
||||
strings.add (String (startOfLine, endOfLine));
|
||||
++numLines;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return numLines;
|
||||
}
|
||||
|
||||
StringArray StringArray::fromTokens (const String& stringToTokenise,
|
||||
bool preserveQuotedStrings)
|
||||
{
|
||||
StringArray s;
|
||||
s.addTokens (stringToTokenise, preserveQuotedStrings);
|
||||
return s;
|
||||
}
|
||||
|
||||
StringArray StringArray::fromTokens (const String& stringToTokenise,
|
||||
const String& breakCharacters,
|
||||
const String& quoteCharacters)
|
||||
{
|
||||
StringArray s;
|
||||
s.addTokens (stringToTokenise, breakCharacters, quoteCharacters);
|
||||
return s;
|
||||
}
|
||||
|
||||
StringArray StringArray::fromLines (const String& stringToBreakUp)
|
||||
{
|
||||
StringArray s;
|
||||
s.addLines (stringToBreakUp);
|
||||
return s;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void StringArray::removeDuplicates (const bool ignoreCase)
|
||||
{
|
||||
for (int i = 0; i < size() - 1; ++i)
|
||||
{
|
||||
const String s (strings.getReference(i));
|
||||
|
||||
int nextIndex = i + 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
nextIndex = indexOf (s, ignoreCase, nextIndex);
|
||||
|
||||
if (nextIndex < 0)
|
||||
break;
|
||||
|
||||
strings.remove (nextIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StringArray::appendNumbersToDuplicates (const bool ignoreCase,
|
||||
const bool appendNumberToFirstInstance,
|
||||
CharPointer_UTF8 preNumberString,
|
||||
CharPointer_UTF8 postNumberString)
|
||||
{
|
||||
CharPointer_UTF8 defaultPre (" ("), defaultPost (")");
|
||||
|
||||
if (preNumberString.getAddress() == nullptr)
|
||||
preNumberString = defaultPre;
|
||||
|
||||
if (postNumberString.getAddress() == nullptr)
|
||||
postNumberString = defaultPost;
|
||||
|
||||
for (int i = 0; i < size() - 1; ++i)
|
||||
{
|
||||
String& s = strings.getReference(i);
|
||||
|
||||
int nextIndex = indexOf (s, ignoreCase, i + 1);
|
||||
|
||||
if (nextIndex >= 0)
|
||||
{
|
||||
const String original (s);
|
||||
|
||||
int number = 0;
|
||||
|
||||
if (appendNumberToFirstInstance)
|
||||
s = original + String (preNumberString) + String (++number) + String (postNumberString);
|
||||
else
|
||||
++number;
|
||||
|
||||
while (nextIndex >= 0)
|
||||
{
|
||||
set (nextIndex, (*this)[nextIndex] + String (preNumberString) + String (++number) + String (postNumberString));
|
||||
nextIndex = indexOf (original, ignoreCase, nextIndex + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StringArray::ensureStorageAllocated (int minNumElements)
|
||||
{
|
||||
strings.ensureStorageAllocated (minNumElements);
|
||||
}
|
||||
|
||||
void StringArray::minimiseStorageOverheads()
|
||||
{
|
||||
strings.minimiseStorageOverheads();
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -1,415 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_TEXT_STRINGARRAY_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_TEXT_STRINGARRAY_H_INCLUDED
|
||||
|
||||
#include <beast/strings/String.h>
|
||||
#include <beast/module/core/containers/Array.h>
|
||||
#include <beast/module/core/threads/CriticalSection.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A special array for holding a list of strings.
|
||||
|
||||
@see String, StringPairArray
|
||||
*/
|
||||
class StringArray
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty string array */
|
||||
StringArray() noexcept;
|
||||
|
||||
/** Creates a copy of another string array */
|
||||
StringArray (const StringArray& other);
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
StringArray (StringArray&& other) noexcept;
|
||||
#endif
|
||||
|
||||
/** Creates an array containing a single string. */
|
||||
explicit StringArray (const String& firstValue);
|
||||
|
||||
/** Creates an array from a raw array of strings.
|
||||
@param strings an array of strings to add
|
||||
@param numberOfStrings how many items there are in the array
|
||||
*/
|
||||
StringArray (const String* strings, int numberOfStrings);
|
||||
|
||||
/** Creates a copy of an array of string literals.
|
||||
@param strings an array of strings to add. Null pointers in the array will be
|
||||
treated as empty strings
|
||||
@param numberOfStrings how many items there are in the array
|
||||
*/
|
||||
StringArray (const char* const* strings, int numberOfStrings);
|
||||
|
||||
/** Creates a copy of a null-terminated array of string literals.
|
||||
|
||||
Each item from the array passed-in is added, until it encounters a null pointer,
|
||||
at which point it stops.
|
||||
*/
|
||||
explicit StringArray (const char* const* strings);
|
||||
|
||||
/** Creates a copy of a null-terminated array of string literals.
|
||||
Each item from the array passed-in is added, until it encounters a null pointer,
|
||||
at which point it stops.
|
||||
*/
|
||||
explicit StringArray (const wchar_t* const* strings);
|
||||
|
||||
/** Creates a copy of an array of string literals.
|
||||
@param strings an array of strings to add. Null pointers in the array will be
|
||||
treated as empty strings
|
||||
@param numberOfStrings how many items there are in the array
|
||||
*/
|
||||
StringArray (const wchar_t* const* strings, int numberOfStrings);
|
||||
|
||||
/** Destructor. */
|
||||
~StringArray();
|
||||
|
||||
/** Copies the contents of another string array into this one */
|
||||
StringArray& operator= (const StringArray& other);
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
StringArray& operator= (StringArray&& other) noexcept;
|
||||
#endif
|
||||
|
||||
/** Swaps the contents of this and another StringArray. */
|
||||
void swapWith (StringArray& other) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Compares two arrays.
|
||||
Comparisons are case-sensitive.
|
||||
@returns true only if the other array contains exactly the same strings in the same order
|
||||
*/
|
||||
bool operator== (const StringArray& other) const noexcept;
|
||||
|
||||
/** Compares two arrays.
|
||||
Comparisons are case-sensitive.
|
||||
@returns false if the other array contains exactly the same strings in the same order
|
||||
*/
|
||||
bool operator!= (const StringArray& other) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the number of strings in the array */
|
||||
inline int size() const noexcept { return strings.size(); };
|
||||
|
||||
/** Returns one of the strings from the array.
|
||||
|
||||
If the index is out-of-range, an empty string is returned.
|
||||
|
||||
Obviously the reference returned shouldn't be stored for later use, as the
|
||||
string it refers to may disappear when the array changes.
|
||||
*/
|
||||
const String& operator[] (int index) const noexcept;
|
||||
|
||||
/** Returns a reference to one of the strings in the array.
|
||||
This lets you modify a string in-place in the array, but you must be sure that
|
||||
the index is in-range.
|
||||
*/
|
||||
String& getReference (int index) noexcept;
|
||||
|
||||
/** Returns a pointer to the first String in the array.
|
||||
This method is provided for compatibility with standard C++ iteration mechanisms.
|
||||
*/
|
||||
inline String* begin() const noexcept
|
||||
{
|
||||
return strings.begin();
|
||||
}
|
||||
|
||||
/** Returns a pointer to the String which follows the last element in the array.
|
||||
This method is provided for compatibility with standard C++ iteration mechanisms.
|
||||
*/
|
||||
inline String* end() const noexcept
|
||||
{
|
||||
return strings.end();
|
||||
}
|
||||
|
||||
/** Searches for a string in the array.
|
||||
|
||||
The comparison will be case-insensitive if the ignoreCase parameter is true.
|
||||
|
||||
@returns true if the string is found inside the array
|
||||
*/
|
||||
bool contains (const String& stringToLookFor,
|
||||
bool ignoreCase = false) const;
|
||||
|
||||
/** Searches for a string in the array.
|
||||
|
||||
The comparison will be case-insensitive if the ignoreCase parameter is true.
|
||||
|
||||
@param stringToLookFor the string to try to find
|
||||
@param ignoreCase whether the comparison should be case-insensitive
|
||||
@param startIndex the first index to start searching from
|
||||
@returns the index of the first occurrence of the string in this array,
|
||||
or -1 if it isn't found.
|
||||
*/
|
||||
int indexOf (const String& stringToLookFor,
|
||||
bool ignoreCase = false,
|
||||
int startIndex = 0) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Appends a string at the end of the array. */
|
||||
void add (const String& stringToAdd);
|
||||
|
||||
/** Inserts a string into the array.
|
||||
|
||||
This will insert a string into the array at the given index, moving
|
||||
up the other elements to make room for it.
|
||||
If the index is less than zero or greater than the size of the array,
|
||||
the new string will be added to the end of the array.
|
||||
*/
|
||||
void insert (int index, const String& stringToAdd);
|
||||
|
||||
/** Adds a string to the array as long as it's not already in there.
|
||||
|
||||
The search can optionally be case-insensitive.
|
||||
*/
|
||||
void addIfNotAlreadyThere (const String& stringToAdd, bool ignoreCase = false);
|
||||
|
||||
/** Replaces one of the strings in the array with another one.
|
||||
|
||||
If the index is higher than the array's size, the new string will be
|
||||
added to the end of the array; if it's less than zero nothing happens.
|
||||
*/
|
||||
void set (int index, const String& newString);
|
||||
|
||||
/** Appends some strings from another array to the end of this one.
|
||||
|
||||
@param other the array to add
|
||||
@param startIndex the first element of the other array to add
|
||||
@param numElementsToAdd the maximum number of elements to add (if this is
|
||||
less than zero, they are all added)
|
||||
*/
|
||||
void addArray (const StringArray& other,
|
||||
int startIndex = 0,
|
||||
int numElementsToAdd = -1);
|
||||
|
||||
/** Breaks up a string into tokens and adds them to this array.
|
||||
|
||||
This will tokenise the given string using whitespace characters as the
|
||||
token delimiters, and will add these tokens to the end of the array.
|
||||
@returns the number of tokens added
|
||||
@see fromTokens
|
||||
*/
|
||||
int addTokens (const String& stringToTokenise,
|
||||
bool preserveQuotedStrings);
|
||||
|
||||
/** Breaks up a string into tokens and adds them to this array.
|
||||
|
||||
This will tokenise the given string (using the string passed in to define the
|
||||
token delimiters), and will add these tokens to the end of the array.
|
||||
|
||||
@param stringToTokenise the string to tokenise
|
||||
@param breakCharacters a string of characters, any of which will be considered
|
||||
to be a token delimiter.
|
||||
@param quoteCharacters if this string isn't empty, it defines a set of characters
|
||||
which are treated as quotes. Any text occurring
|
||||
between quotes is not broken up into tokens.
|
||||
@returns the number of tokens added
|
||||
@see fromTokens
|
||||
*/
|
||||
int addTokens (const String& stringToTokenise,
|
||||
const String& breakCharacters,
|
||||
const String& quoteCharacters);
|
||||
|
||||
/** Breaks up a string into lines and adds them to this array.
|
||||
|
||||
This breaks a string down into lines separated by \\n or \\r\\n, and adds each line
|
||||
to the array. Line-break characters are omitted from the strings that are added to
|
||||
the array.
|
||||
*/
|
||||
int addLines (const String& stringToBreakUp);
|
||||
|
||||
/** Returns an array containing the tokens in a given string.
|
||||
|
||||
This will tokenise the given string using whitespace characters as the
|
||||
token delimiters, and return these tokens as an array.
|
||||
@see addTokens
|
||||
*/
|
||||
static StringArray fromTokens (const String& stringToTokenise,
|
||||
bool preserveQuotedStrings);
|
||||
|
||||
/** Returns an array containing the tokens in a given string.
|
||||
|
||||
This will tokenise the given string using whitespace characters as the
|
||||
token delimiters, and return these tokens as an array.
|
||||
|
||||
@param stringToTokenise the string to tokenise
|
||||
@param breakCharacters a string of characters, any of which will be considered
|
||||
to be a token delimiter.
|
||||
@param quoteCharacters if this string isn't empty, it defines a set of characters
|
||||
which are treated as quotes. Any text occurring
|
||||
between quotes is not broken up into tokens.
|
||||
@see addTokens
|
||||
*/
|
||||
static StringArray fromTokens (const String& stringToTokenise,
|
||||
const String& breakCharacters,
|
||||
const String& quoteCharacters);
|
||||
|
||||
/** Returns an array containing the lines in a given string.
|
||||
|
||||
This breaks a string down into lines separated by \\n or \\r\\n, and returns an
|
||||
array containing these lines. Line-break characters are omitted from the strings that
|
||||
are added to the array.
|
||||
*/
|
||||
static StringArray fromLines (const String& stringToBreakUp);
|
||||
|
||||
//==============================================================================
|
||||
/** Removes all elements from the array. */
|
||||
void clear();
|
||||
|
||||
/** Removes a string from the array.
|
||||
|
||||
If the index is out-of-range, no action will be taken.
|
||||
*/
|
||||
void remove (int index);
|
||||
|
||||
/** Finds a string in the array and removes it.
|
||||
|
||||
This will remove the first occurrence of the given string from the array. The
|
||||
comparison may be case-insensitive depending on the ignoreCase parameter.
|
||||
*/
|
||||
void removeString (const String& stringToRemove,
|
||||
bool ignoreCase = false);
|
||||
|
||||
/** Removes a range of elements from the array.
|
||||
|
||||
This will remove a set of elements, starting from the given index,
|
||||
and move subsequent elements down to close the gap.
|
||||
|
||||
If the range extends beyond the bounds of the array, it will
|
||||
be safely clipped to the size of the array.
|
||||
|
||||
@param startIndex the index of the first element to remove
|
||||
@param numberToRemove how many elements should be removed
|
||||
*/
|
||||
void removeRange (int startIndex, int numberToRemove);
|
||||
|
||||
/** Removes any duplicated elements from the array.
|
||||
|
||||
If any string appears in the array more than once, only the first occurrence of
|
||||
it will be retained.
|
||||
|
||||
@param ignoreCase whether to use a case-insensitive comparison
|
||||
*/
|
||||
void removeDuplicates (bool ignoreCase);
|
||||
|
||||
/** Removes empty strings from the array.
|
||||
|
||||
@param removeWhitespaceStrings if true, strings that only contain whitespace
|
||||
characters will also be removed
|
||||
*/
|
||||
void removeEmptyStrings (bool removeWhitespaceStrings = true);
|
||||
|
||||
/** Moves one of the strings to a different position.
|
||||
|
||||
This will move the string to a specified index, shuffling along
|
||||
any intervening elements as required.
|
||||
|
||||
So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling
|
||||
move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }.
|
||||
|
||||
@param currentIndex the index of the value to be moved. If this isn't a
|
||||
valid index, then nothing will be done
|
||||
@param newIndex the index at which you'd like this value to end up. If this
|
||||
is less than zero, the value will be moved to the end
|
||||
of the array
|
||||
*/
|
||||
void move (int currentIndex, int newIndex) noexcept;
|
||||
|
||||
/** Deletes any whitespace characters from the starts and ends of all the strings. */
|
||||
void trim();
|
||||
|
||||
/** Adds numbers to the strings in the array, to make each string unique.
|
||||
|
||||
This will add numbers to the ends of groups of similar strings.
|
||||
e.g. if there are two "moose" strings, they will become "moose (1)" and "moose (2)"
|
||||
|
||||
@param ignoreCaseWhenComparing whether the comparison used is case-insensitive
|
||||
@param appendNumberToFirstInstance whether the first of a group of similar strings
|
||||
also has a number appended to it.
|
||||
@param preNumberString when adding a number, this string is added before the number.
|
||||
If you pass 0, a default string will be used, which adds
|
||||
brackets around the number.
|
||||
@param postNumberString this string is appended after any numbers that are added.
|
||||
If you pass 0, a default string will be used, which adds
|
||||
brackets around the number.
|
||||
*/
|
||||
void appendNumbersToDuplicates (bool ignoreCaseWhenComparing,
|
||||
bool appendNumberToFirstInstance,
|
||||
CharPointer_UTF8 preNumberString = CharPointer_UTF8 (nullptr),
|
||||
CharPointer_UTF8 postNumberString = CharPointer_UTF8 (nullptr));
|
||||
|
||||
//==============================================================================
|
||||
/** Joins the strings in the array together into one string.
|
||||
|
||||
This will join a range of elements from the array into a string, separating
|
||||
them with a given string.
|
||||
|
||||
e.g. joinIntoString (",") will turn an array of "a" "b" and "c" into "a,b,c".
|
||||
|
||||
@param separatorString the string to insert between all the strings
|
||||
@param startIndex the first element to join
|
||||
@param numberOfElements how many elements to join together. If this is less
|
||||
than zero, all available elements will be used.
|
||||
*/
|
||||
String joinIntoString (const String& separatorString,
|
||||
int startIndex = 0,
|
||||
int numberOfElements = -1) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Sorts the array into alphabetical order.
|
||||
|
||||
@param ignoreCase if true, the comparisons used will be case-sensitive.
|
||||
*/
|
||||
void sort (bool ignoreCase);
|
||||
|
||||
//==============================================================================
|
||||
/** Increases the array's internal storage to hold a minimum number of elements.
|
||||
|
||||
Calling this before adding a large known number of elements means that
|
||||
the array won't have to keep dynamically resizing itself as the elements
|
||||
are added, and it'll therefore be more efficient.
|
||||
*/
|
||||
void ensureStorageAllocated (int minNumElements);
|
||||
|
||||
//==============================================================================
|
||||
/** Reduces the amount of storage being used by the array.
|
||||
|
||||
Arrays typically allocate slightly more storage than they need, and after
|
||||
removing elements, they may have quite a lot of unused space allocated.
|
||||
This method will reduce the amount of allocated storage to a minimum.
|
||||
*/
|
||||
void minimiseStorageOverheads();
|
||||
|
||||
|
||||
private:
|
||||
Array <String> strings;
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_STRINGARRAY_H_INCLUDED
|
||||
@@ -1,149 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
StringPairArray::StringPairArray (const bool ignoreCase_)
|
||||
: ignoreCase (ignoreCase_)
|
||||
{
|
||||
}
|
||||
|
||||
StringPairArray::StringPairArray (const StringPairArray& other)
|
||||
: keys (other.keys),
|
||||
values (other.values),
|
||||
ignoreCase (other.ignoreCase)
|
||||
{
|
||||
}
|
||||
|
||||
StringPairArray::~StringPairArray()
|
||||
{
|
||||
}
|
||||
|
||||
StringPairArray& StringPairArray::operator= (const StringPairArray& other)
|
||||
{
|
||||
keys = other.keys;
|
||||
values = other.values;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void StringPairArray::swapWith (StringPairArray& other)
|
||||
{
|
||||
std::swap (ignoreCase, other.ignoreCase);
|
||||
keys.swapWith (other.keys);
|
||||
values.swapWith (other.values);
|
||||
}
|
||||
|
||||
bool StringPairArray::operator== (const StringPairArray& other) const
|
||||
{
|
||||
for (int i = keys.size(); --i >= 0;)
|
||||
if (other [keys[i]] != values[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StringPairArray::operator!= (const StringPairArray& other) const
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
const String& StringPairArray::operator[] (const String& key) const
|
||||
{
|
||||
return values [keys.indexOf (key, ignoreCase)];
|
||||
}
|
||||
|
||||
String StringPairArray::getValue (const String& key, const String& defaultReturnValue) const
|
||||
{
|
||||
const int i = keys.indexOf (key, ignoreCase);
|
||||
|
||||
if (i >= 0)
|
||||
return values[i];
|
||||
|
||||
return defaultReturnValue;
|
||||
}
|
||||
|
||||
void StringPairArray::set (const String& key, const String& value)
|
||||
{
|
||||
const int i = keys.indexOf (key, ignoreCase);
|
||||
|
||||
if (i >= 0)
|
||||
{
|
||||
values.set (i, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
keys.add (key);
|
||||
values.add (value);
|
||||
}
|
||||
}
|
||||
|
||||
void StringPairArray::addArray (const StringPairArray& other)
|
||||
{
|
||||
for (int i = 0; i < other.size(); ++i)
|
||||
set (other.keys[i], other.values[i]);
|
||||
}
|
||||
|
||||
void StringPairArray::clear()
|
||||
{
|
||||
keys.clear();
|
||||
values.clear();
|
||||
}
|
||||
|
||||
void StringPairArray::remove (const String& key)
|
||||
{
|
||||
remove (keys.indexOf (key, ignoreCase));
|
||||
}
|
||||
|
||||
void StringPairArray::remove (const int index)
|
||||
{
|
||||
keys.remove (index);
|
||||
values.remove (index);
|
||||
}
|
||||
|
||||
void StringPairArray::setIgnoresCase (const bool shouldIgnoreCase)
|
||||
{
|
||||
ignoreCase = shouldIgnoreCase;
|
||||
}
|
||||
|
||||
String StringPairArray::getDescription() const
|
||||
{
|
||||
String s;
|
||||
|
||||
for (int i = 0; i < keys.size(); ++i)
|
||||
{
|
||||
s << keys[i] << " = " << values[i];
|
||||
if (i < keys.size())
|
||||
s << ", ";
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void StringPairArray::minimiseStorageOverheads()
|
||||
{
|
||||
keys.minimiseStorageOverheads();
|
||||
values.minimiseStorageOverheads();
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -1,161 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_TEXT_STRINGPAIRARRAY_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_TEXT_STRINGPAIRARRAY_H_INCLUDED
|
||||
|
||||
#include <beast/module/core/text/StringArray.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A container for holding a set of strings which are keyed by another string.
|
||||
|
||||
@see StringArray
|
||||
*/
|
||||
class StringPairArray
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty array */
|
||||
StringPairArray (bool ignoreCaseWhenComparingKeys = true);
|
||||
|
||||
/** Creates a copy of another array */
|
||||
StringPairArray (const StringPairArray& other);
|
||||
|
||||
/** Destructor. */
|
||||
~StringPairArray();
|
||||
|
||||
/** Copies the contents of another string array into this one */
|
||||
StringPairArray& operator= (const StringPairArray& other);
|
||||
|
||||
/** Swap the contents of this array with another. */
|
||||
void swapWith (StringPairArray& other);
|
||||
|
||||
//==============================================================================
|
||||
/** Compares two arrays.
|
||||
Comparisons are case-sensitive.
|
||||
@returns true only if the other array contains exactly the same strings with the same keys
|
||||
*/
|
||||
bool operator== (const StringPairArray& other) const;
|
||||
|
||||
/** Compares two arrays.
|
||||
Comparisons are case-sensitive.
|
||||
@returns false if the other array contains exactly the same strings with the same keys
|
||||
*/
|
||||
bool operator!= (const StringPairArray& other) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Finds the value corresponding to a key string.
|
||||
|
||||
If no such key is found, this will just return an empty string. To check whether
|
||||
a given key actually exists (because it might actually be paired with an empty string), use
|
||||
the getAllKeys() method to obtain a list.
|
||||
|
||||
Obviously the reference returned shouldn't be stored for later use, as the
|
||||
string it refers to may disappear when the array changes.
|
||||
|
||||
@see getValue
|
||||
*/
|
||||
const String& operator[] (const String& key) const;
|
||||
|
||||
/** Finds the value corresponding to a key string.
|
||||
|
||||
If no such key is found, this will just return the value provided as a default.
|
||||
|
||||
@see operator[]
|
||||
*/
|
||||
String getValue (const String& key, const String& defaultReturnValue) const;
|
||||
|
||||
|
||||
/** Returns a list of all keys in the array. */
|
||||
const StringArray& getAllKeys() const noexcept { return keys; }
|
||||
|
||||
/** Returns a list of all values in the array. */
|
||||
const StringArray& getAllValues() const noexcept { return values; }
|
||||
|
||||
/** Returns the number of strings in the array */
|
||||
inline int size() const noexcept { return keys.size(); };
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** Adds or amends a key/value pair.
|
||||
|
||||
If a value already exists with this key, its value will be overwritten,
|
||||
otherwise the key/value pair will be added to the array.
|
||||
*/
|
||||
void set (const String& key, const String& value);
|
||||
|
||||
/** Adds the items from another array to this one.
|
||||
|
||||
This is equivalent to using set() to add each of the pairs from the other array.
|
||||
*/
|
||||
void addArray (const StringPairArray& other);
|
||||
|
||||
//==============================================================================
|
||||
/** Removes all elements from the array. */
|
||||
void clear();
|
||||
|
||||
/** Removes a string from the array based on its key.
|
||||
|
||||
If the key isn't found, nothing will happen.
|
||||
*/
|
||||
void remove (const String& key);
|
||||
|
||||
/** Removes a string from the array based on its index.
|
||||
|
||||
If the index is out-of-range, no action will be taken.
|
||||
*/
|
||||
void remove (int index);
|
||||
|
||||
//==============================================================================
|
||||
/** Indicates whether to use a case-insensitive search when looking up a key string.
|
||||
*/
|
||||
void setIgnoresCase (bool shouldIgnoreCase);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a descriptive string containing the items.
|
||||
This is handy for dumping the contents of an array.
|
||||
*/
|
||||
String getDescription() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Reduces the amount of storage being used by the array.
|
||||
|
||||
Arrays typically allocate slightly more storage than they need, and after
|
||||
removing elements, they may have quite a lot of unused space allocated.
|
||||
This method will reduce the amount of allocated storage to a minimum.
|
||||
*/
|
||||
void minimiseStorageOverheads();
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
StringArray keys, values;
|
||||
bool ignoreCase;
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_STRINGPAIRARRAY_H_INCLUDED
|
||||
@@ -17,6 +17,10 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/module/core/thread/DeadlineTimer.h>
|
||||
#include <cassert>
|
||||
#include <mutex>
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
@@ -24,7 +28,6 @@ class DeadlineTimer::Manager
|
||||
: protected Thread
|
||||
{
|
||||
private:
|
||||
using LockType = CriticalSection;
|
||||
using Items = List <DeadlineTimer>;
|
||||
|
||||
public:
|
||||
@@ -38,7 +41,7 @@ public:
|
||||
signalThreadShouldExit ();
|
||||
notify ();
|
||||
waitForThreadToExit ();
|
||||
bassert (m_items.empty ());
|
||||
assert (m_items.empty ());
|
||||
}
|
||||
|
||||
static
|
||||
@@ -55,9 +58,9 @@ public:
|
||||
void activate (DeadlineTimer& timer,
|
||||
double secondsRecurring, RelativeTime const& when)
|
||||
{
|
||||
bassert (secondsRecurring >= 0);
|
||||
assert (secondsRecurring >= 0);
|
||||
|
||||
std::lock_guard <LockType> lock (m_mutex);
|
||||
std::lock_guard <std::recursive_mutex> lock (m_mutex);
|
||||
|
||||
if (timer.m_isActive)
|
||||
{
|
||||
@@ -80,7 +83,7 @@ public:
|
||||
//
|
||||
void deactivate (DeadlineTimer& timer)
|
||||
{
|
||||
std::lock_guard <LockType> lock (m_mutex);
|
||||
std::lock_guard <std::recursive_mutex> lock (m_mutex);
|
||||
|
||||
if (timer.m_isActive)
|
||||
{
|
||||
@@ -103,7 +106,7 @@ public:
|
||||
DeadlineTimer* timer (nullptr);
|
||||
|
||||
{
|
||||
std::lock_guard <LockType> lock (m_mutex);
|
||||
std::lock_guard <std::recursive_mutex> lock (m_mutex);
|
||||
|
||||
// See if a timer expired
|
||||
if (! m_items.empty ())
|
||||
@@ -114,7 +117,7 @@ public:
|
||||
if (timer->m_notificationTime <= currentTime)
|
||||
{
|
||||
// Expired, remove it from the list.
|
||||
bassert (timer->m_isActive);
|
||||
assert (timer->m_isActive);
|
||||
m_items.pop_front ();
|
||||
|
||||
// Is the timer recurring?
|
||||
@@ -144,7 +147,7 @@ public:
|
||||
timer->m_notificationTime - currentTime).inSeconds ();
|
||||
|
||||
// Can't be zero and come into the else clause.
|
||||
bassert (seconds != 0);
|
||||
assert (seconds != 0);
|
||||
|
||||
// Don't call the listener
|
||||
timer = nullptr;
|
||||
@@ -160,7 +163,7 @@ public:
|
||||
//
|
||||
int const milliSeconds (std::max (
|
||||
static_cast <int> (seconds * 1000 + 0.5), 1));
|
||||
bassert (milliSeconds > 0);
|
||||
assert (milliSeconds > 0);
|
||||
wait (milliSeconds);
|
||||
}
|
||||
else if (seconds == 0)
|
||||
@@ -209,7 +212,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
CriticalSection m_mutex;
|
||||
std::recursive_mutex m_mutex;
|
||||
Items m_items;
|
||||
};
|
||||
|
||||
@@ -233,7 +236,7 @@ void DeadlineTimer::cancel ()
|
||||
|
||||
void DeadlineTimer::setExpiration (double secondsUntilDeadline)
|
||||
{
|
||||
bassert (secondsUntilDeadline != 0);
|
||||
assert (secondsUntilDeadline != 0);
|
||||
|
||||
RelativeTime const when (
|
||||
RelativeTime::fromStartup() + secondsUntilDeadline);
|
||||
@@ -243,7 +246,7 @@ void DeadlineTimer::setExpiration (double secondsUntilDeadline)
|
||||
|
||||
void DeadlineTimer::setRecurringExpiration (double secondsUntilDeadline)
|
||||
{
|
||||
bassert (secondsUntilDeadline != 0);
|
||||
assert (secondsUntilDeadline != 0);
|
||||
|
||||
RelativeTime const when (
|
||||
RelativeTime::fromStartup() + secondsUntilDeadline);
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef BEAST_MODULE_CORE_THREAD_DEADLINETIMER_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_THREAD_DEADLINETIMER_H_INCLUDED
|
||||
|
||||
#include <beast/chrono/RelativeTime.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** Provides periodic or one time notifications at a specified time interval.
|
||||
|
||||
@@ -20,61 +20,5 @@
|
||||
#ifndef BEAST_MODULE_CORE_THREAD_MUTEXTRAITS_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_THREAD_MUTEXTRAITS_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
/** Adapt a Mutex type to meet the boost::Mutex concept requirements.
|
||||
The default implementation assumes adherance to the boost::Mutex concepts,
|
||||
with one important exception. We make the member functions const, for
|
||||
convenience.
|
||||
*/
|
||||
template <typename Mutex>
|
||||
struct MutexTraits
|
||||
{
|
||||
// BasicLockable
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts.basic_lockable
|
||||
//
|
||||
static inline void lock (Mutex const& mutex) noexcept
|
||||
{
|
||||
(const_cast <Mutex&> (mutex)).lock ();
|
||||
}
|
||||
|
||||
static inline void unlock (Mutex const& mutex) noexcept
|
||||
{
|
||||
(const_cast <Mutex&> (mutex)).unlock ();
|
||||
}
|
||||
|
||||
// Lockable
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts.basic_lockable
|
||||
//
|
||||
static inline bool try_lock (Mutex const& mutex) noexcept
|
||||
{
|
||||
return (const_cast <Mutex&> (mutex)).try_lock ();
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** MutexTraits Specialization for a beast CriticalSection. */
|
||||
template <>
|
||||
struct MutexTraits <CriticalSection>
|
||||
{
|
||||
static inline void lock (CriticalSection const& mutex) noexcept
|
||||
{
|
||||
mutex.lock ();
|
||||
}
|
||||
|
||||
static inline void unlock (CriticalSection const& mutex) noexcept
|
||||
{
|
||||
mutex.unlock ();
|
||||
}
|
||||
|
||||
static inline bool try_lock (CriticalSection const& mutex) noexcept
|
||||
{
|
||||
return mutex.try_lock ();
|
||||
}
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <cassert>
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -108,7 +109,7 @@ void Workers::pauseAllThreadsAndWait ()
|
||||
|
||||
m_allPaused.wait ();
|
||||
|
||||
bassert (numberOfCurrentlyRunningTasks () == 0);
|
||||
assert (numberOfCurrentlyRunningTasks () == 0);
|
||||
}
|
||||
|
||||
void Workers::addTask ()
|
||||
|
||||
@@ -1,267 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_MODULE_CORE_THREADS_CRITICALSECTION_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_THREADS_CRITICALSECTION_H_INCLUDED
|
||||
|
||||
#include <beast/module/core/threads/ScopedLock.h>
|
||||
#include <cstdint>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A re-entrant mutex.
|
||||
|
||||
A CriticalSection acts as a re-entrant mutex object. The best way to lock and unlock
|
||||
one of these is by using RAII in the form of a local ScopedLock object - have a look
|
||||
through the codebase for many examples of how to do this.
|
||||
|
||||
@see ScopedLock, ScopedTryLock, ScopedUnlock, SpinLock, Thread
|
||||
*/
|
||||
class CriticalSection
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a CriticalSection object. */
|
||||
CriticalSection() noexcept;
|
||||
|
||||
CriticalSection (CriticalSection const&) = delete;
|
||||
CriticalSection& operator= (CriticalSection const&) = delete;
|
||||
|
||||
/** Destructor.
|
||||
If the critical section is deleted whilst locked, any subsequent behaviour
|
||||
is unpredictable.
|
||||
*/
|
||||
~CriticalSection() noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Acquires the lock.
|
||||
|
||||
If the lock is already held by the caller thread, the method returns immediately.
|
||||
If the lock is currently held by another thread, this will wait until it becomes free.
|
||||
|
||||
It's strongly recommended that you never call this method directly - instead use the
|
||||
ScopedLock class to manage the locking using an RAII pattern instead.
|
||||
|
||||
@see exit, tryEnter, ScopedLock
|
||||
*/
|
||||
void enter() const noexcept;
|
||||
|
||||
/** Attempts to lock this critical section without blocking.
|
||||
|
||||
This method behaves identically to CriticalSection::enter, except that the caller thread
|
||||
does not wait if the lock is currently held by another thread but returns false immediately.
|
||||
|
||||
@returns false if the lock is currently held by another thread, true otherwise.
|
||||
@see enter
|
||||
*/
|
||||
bool tryEnter() const noexcept;
|
||||
|
||||
/** Releases the lock.
|
||||
|
||||
If the caller thread hasn't got the lock, this can have unpredictable results.
|
||||
|
||||
If the enter() method has been called multiple times by the thread, each
|
||||
call must be matched by a call to exit() before other threads will be allowed
|
||||
to take over the lock.
|
||||
|
||||
@see enter, ScopedLock
|
||||
*/
|
||||
void exit() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Provides the type of scoped lock to use with a CriticalSection. */
|
||||
using ScopedLockType = GenericScopedLock <CriticalSection>;
|
||||
|
||||
/** Provides the type of scoped unlocker to use with a CriticalSection. */
|
||||
using ScopedUnlockType = GenericScopedUnlock <CriticalSection>;
|
||||
|
||||
/** Provides the type of scoped try-locker to use with a CriticalSection. */
|
||||
using ScopedTryLockType = GenericScopedTryLock <CriticalSection>;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Boost concept compatibility
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts
|
||||
//
|
||||
|
||||
// BasicLockable
|
||||
inline void lock () const noexcept { enter (); }
|
||||
inline void unlock () const noexcept { exit (); }
|
||||
|
||||
// Lockable
|
||||
inline bool try_lock () const noexcept { return tryEnter (); }
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
#if BEAST_WINDOWS
|
||||
// To avoid including windows.h in the public Beast headers, we'll just allocate
|
||||
// a block of memory here that's big enough to be used internally as a windows
|
||||
// CRITICAL_SECTION structure.
|
||||
#if BEAST_64BIT
|
||||
std::uint8_t section[44];
|
||||
#else
|
||||
std::uint8_t section[24];
|
||||
#endif
|
||||
#else
|
||||
mutable pthread_mutex_t mutex;
|
||||
#endif
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A class that can be used in place of a real CriticalSection object, but which
|
||||
doesn't perform any locking.
|
||||
|
||||
This is currently used by some templated classes, and most compilers should
|
||||
manage to optimise it out of existence.
|
||||
|
||||
@see CriticalSection, Array, SharedObjectArray
|
||||
*/
|
||||
class DummyCriticalSection
|
||||
{
|
||||
public:
|
||||
DummyCriticalSection() = default;
|
||||
DummyCriticalSection (DummyCriticalSection const&) = delete;
|
||||
DummyCriticalSection& operator= (DummyCriticalSection const&) = delete;
|
||||
~DummyCriticalSection() = default;
|
||||
|
||||
inline void enter() const noexcept {}
|
||||
inline bool tryEnter() const noexcept { return true; }
|
||||
inline void exit() const noexcept {}
|
||||
|
||||
//==============================================================================
|
||||
/** A dummy scoped-lock type to use with a dummy critical section. */
|
||||
struct ScopedLockType
|
||||
{
|
||||
ScopedLockType (const DummyCriticalSection&) noexcept {}
|
||||
};
|
||||
|
||||
/** A dummy scoped-unlocker type to use with a dummy critical section. */
|
||||
using ScopedUnlockType = ScopedLockType;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Automatically locks and unlocks a CriticalSection object.
|
||||
|
||||
Use one of these as a local variable to provide RAII-based locking of a CriticalSection.
|
||||
|
||||
e.g. @code
|
||||
|
||||
CriticalSection myCriticalSection;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const ScopedLock myScopedLock (myCriticalSection);
|
||||
// myCriticalSection is now locked
|
||||
|
||||
...do some stuff...
|
||||
|
||||
// myCriticalSection gets unlocked here.
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see CriticalSection, ScopedUnlock
|
||||
*/
|
||||
using ScopedLock = CriticalSection::ScopedLockType;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Automatically unlocks and re-locks a CriticalSection object.
|
||||
|
||||
This is the reverse of a ScopedLock object - instead of locking the critical
|
||||
section for the lifetime of this object, it unlocks it.
|
||||
|
||||
Make sure you don't try to unlock critical sections that aren't actually locked!
|
||||
|
||||
e.g. @code
|
||||
|
||||
CriticalSection myCriticalSection;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const ScopedLock myScopedLock (myCriticalSection);
|
||||
// myCriticalSection is now locked
|
||||
|
||||
... do some stuff with it locked ..
|
||||
|
||||
while (xyz)
|
||||
{
|
||||
... do some stuff with it locked ..
|
||||
|
||||
const ScopedUnlock unlocker (myCriticalSection);
|
||||
|
||||
// myCriticalSection is now unlocked for the remainder of this block,
|
||||
// and re-locked at the end.
|
||||
|
||||
...do some stuff with it unlocked ...
|
||||
}
|
||||
|
||||
// myCriticalSection gets unlocked here.
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see CriticalSection, ScopedLock
|
||||
*/
|
||||
using ScopedUnlock = CriticalSection::ScopedUnlockType;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Automatically tries to lock and unlock a CriticalSection object.
|
||||
|
||||
Use one of these as a local variable to control access to a CriticalSection.
|
||||
|
||||
e.g. @code
|
||||
CriticalSection myCriticalSection;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const ScopedTryLock myScopedTryLock (myCriticalSection);
|
||||
|
||||
// Unlike using a ScopedLock, this may fail to actually get the lock, so you
|
||||
// should test this with the isLocked() method before doing your thread-unsafe
|
||||
// action..
|
||||
if (myScopedTryLock.isLocked())
|
||||
{
|
||||
...do some stuff...
|
||||
}
|
||||
else
|
||||
{
|
||||
..our attempt at locking failed because another thread had already locked it..
|
||||
}
|
||||
|
||||
// myCriticalSection gets unlocked here (if it was locked)
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see CriticalSection::tryEnter, ScopedLock, ScopedUnlock, ScopedReadLock
|
||||
*/
|
||||
using ScopedTryLock = CriticalSection::ScopedTryLockType;
|
||||
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_CRITICALSECTION_H_INCLUDED
|
||||
@@ -21,178 +21,12 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <algorithm>
|
||||
#include <thread>
|
||||
#include <beast/module/core/time/Time.h>
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
namespace TimeHelpers
|
||||
{
|
||||
static struct tm millisToLocal (const std::int64_t millis) noexcept
|
||||
{
|
||||
struct tm result;
|
||||
const std::int64_t seconds = millis / 1000;
|
||||
|
||||
if (seconds < 86400LL || seconds >= 2145916800LL)
|
||||
{
|
||||
// use extended maths for dates beyond 1970 to 2037..
|
||||
const int timeZoneAdjustment = 31536000 - (int) (Time (1971, 0, 1, 0, 0).toMilliseconds() / 1000);
|
||||
const std::int64_t jdm = seconds + timeZoneAdjustment + 210866803200LL;
|
||||
|
||||
const int days = (int) (jdm / 86400LL);
|
||||
const int a = 32044 + days;
|
||||
const int b = (4 * a + 3) / 146097;
|
||||
const int c = a - (b * 146097) / 4;
|
||||
const int d = (4 * c + 3) / 1461;
|
||||
const int e = c - (d * 1461) / 4;
|
||||
const int m = (5 * e + 2) / 153;
|
||||
|
||||
result.tm_mday = e - (153 * m + 2) / 5 + 1;
|
||||
result.tm_mon = m + 2 - 12 * (m / 10);
|
||||
result.tm_year = b * 100 + d - 6700 + (m / 10);
|
||||
result.tm_wday = (days + 1) % 7;
|
||||
result.tm_yday = -1;
|
||||
|
||||
int t = (int) (jdm % 86400LL);
|
||||
result.tm_hour = t / 3600;
|
||||
t %= 3600;
|
||||
result.tm_min = t / 60;
|
||||
result.tm_sec = t % 60;
|
||||
result.tm_isdst = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t now = static_cast <time_t> (seconds);
|
||||
|
||||
#if BEAST_WINDOWS
|
||||
#ifdef _INC_TIME_INL
|
||||
if (now >= 0 && now <= 0x793406fff)
|
||||
localtime_s (&result, &now);
|
||||
else
|
||||
zerostruct (result);
|
||||
#else
|
||||
result = *localtime (&now);
|
||||
#endif
|
||||
#else
|
||||
|
||||
localtime_r (&now, &result); // more thread-safe
|
||||
#endif
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int extendedModulo (const std::int64_t value, const int modulo) noexcept
|
||||
{
|
||||
return (int) (value >= 0 ? (value % modulo)
|
||||
: (value - ((value / modulo) + 1) * modulo));
|
||||
}
|
||||
|
||||
static inline String formatString (const String& format, const struct tm* const tm)
|
||||
{
|
||||
#if BEAST_ANDROID
|
||||
using StringType = CharPointer_UTF8;
|
||||
#elif BEAST_WINDOWS
|
||||
using StringType = CharPointer_UTF16;
|
||||
#else
|
||||
using StringType = CharPointer_UTF32;
|
||||
#endif
|
||||
|
||||
for (size_t bufferSize = 256; ; bufferSize += 256)
|
||||
{
|
||||
HeapBlock<StringType::CharType> buffer (bufferSize);
|
||||
|
||||
#if BEAST_ANDROID
|
||||
const size_t numChars = strftime (buffer, bufferSize - 1, format.toUTF8(), tm);
|
||||
#elif BEAST_WINDOWS
|
||||
const size_t numChars = wcsftime (buffer, bufferSize - 1, format.toWideCharPointer(), tm);
|
||||
#else
|
||||
const size_t numChars = wcsftime (buffer, bufferSize - 1, format.toUTF32(), tm);
|
||||
#endif
|
||||
|
||||
if (numChars > 0)
|
||||
return String (StringType (buffer),
|
||||
StringType (buffer) + (int) numChars);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
Time::Time() noexcept
|
||||
: millisSinceEpoch (0)
|
||||
{
|
||||
}
|
||||
|
||||
Time::Time (const Time& other) noexcept
|
||||
: millisSinceEpoch (other.millisSinceEpoch)
|
||||
{
|
||||
}
|
||||
|
||||
Time::Time (const std::int64_t ms) noexcept
|
||||
: millisSinceEpoch (ms)
|
||||
{
|
||||
}
|
||||
|
||||
Time::Time (const int year,
|
||||
const int month,
|
||||
const int day,
|
||||
const int hours,
|
||||
const int minutes,
|
||||
const int seconds,
|
||||
const int milliseconds,
|
||||
const bool useLocalTime) noexcept
|
||||
{
|
||||
bassert (year > 100); // year must be a 4-digit version
|
||||
|
||||
if (year < 1971 || year >= 2038 || ! useLocalTime)
|
||||
{
|
||||
// use extended maths for dates beyond 1970 to 2037..
|
||||
const int timeZoneAdjustment = useLocalTime ? (31536000 - (int) (Time (1971, 0, 1, 0, 0).toMilliseconds() / 1000))
|
||||
: 0;
|
||||
const int a = (13 - month) / 12;
|
||||
const int y = year + 4800 - a;
|
||||
const int jd = day + (153 * (month + 12 * a - 2) + 2) / 5
|
||||
+ (y * 365) + (y / 4) - (y / 100) + (y / 400)
|
||||
- 32045;
|
||||
|
||||
const std::int64_t s = ((std::int64_t) jd) * 86400LL - 210866803200LL;
|
||||
|
||||
millisSinceEpoch = 1000 * (s + (hours * 3600 + minutes * 60 + seconds - timeZoneAdjustment))
|
||||
+ milliseconds;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct tm t;
|
||||
t.tm_year = year - 1900;
|
||||
t.tm_mon = month;
|
||||
t.tm_mday = day;
|
||||
t.tm_hour = hours;
|
||||
t.tm_min = minutes;
|
||||
t.tm_sec = seconds;
|
||||
t.tm_isdst = -1;
|
||||
|
||||
millisSinceEpoch = 1000 * (std::int64_t) mktime (&t);
|
||||
|
||||
if (millisSinceEpoch < 0)
|
||||
millisSinceEpoch = 0;
|
||||
else
|
||||
millisSinceEpoch += milliseconds;
|
||||
}
|
||||
}
|
||||
|
||||
Time::~Time() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
Time& Time::operator= (const Time& other) noexcept
|
||||
{
|
||||
millisSinceEpoch = other.millisSinceEpoch;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
std::int64_t Time::currentTimeMillis() noexcept
|
||||
std::int64_t currentTimeMillis()
|
||||
{
|
||||
#if BEAST_WINDOWS
|
||||
struct _timeb t;
|
||||
@@ -209,172 +43,4 @@ std::int64_t Time::currentTimeMillis() noexcept
|
||||
#endif
|
||||
}
|
||||
|
||||
Time Time::getCurrentTime() noexcept
|
||||
{
|
||||
return Time (currentTimeMillis());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
String Time::toString (const bool includeDate,
|
||||
const bool includeTime,
|
||||
const bool includeSeconds,
|
||||
const bool use24HourClock) const noexcept
|
||||
{
|
||||
String result;
|
||||
|
||||
if (includeDate)
|
||||
{
|
||||
result << getDayOfMonth() << ' '
|
||||
<< getMonthName (true) << ' '
|
||||
<< getYear();
|
||||
|
||||
if (includeTime)
|
||||
result << ' ';
|
||||
}
|
||||
|
||||
if (includeTime)
|
||||
{
|
||||
const int mins = getMinutes();
|
||||
|
||||
result << (use24HourClock ? getHours() : getHoursInAmPmFormat())
|
||||
<< (mins < 10 ? ":0" : ":") << mins;
|
||||
|
||||
if (includeSeconds)
|
||||
{
|
||||
const int secs = getSeconds();
|
||||
result << (secs < 10 ? ":0" : ":") << secs;
|
||||
}
|
||||
|
||||
if (! use24HourClock)
|
||||
result << (isAfternoon() ? "pm" : "am");
|
||||
}
|
||||
|
||||
return result.trimEnd();
|
||||
}
|
||||
|
||||
String Time::formatted (const String& format) const
|
||||
{
|
||||
struct tm t (TimeHelpers::millisToLocal (millisSinceEpoch));
|
||||
return TimeHelpers::formatString (format, &t);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int Time::getYear() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_year + 1900; }
|
||||
int Time::getMonth() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_mon; }
|
||||
int Time::getDayOfYear() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_yday; }
|
||||
int Time::getDayOfMonth() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_mday; }
|
||||
int Time::getDayOfWeek() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_wday; }
|
||||
int Time::getHours() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_hour; }
|
||||
int Time::getMinutes() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_min; }
|
||||
int Time::getSeconds() const noexcept { return TimeHelpers::extendedModulo (millisSinceEpoch / 1000, 60); }
|
||||
int Time::getMilliseconds() const noexcept { return TimeHelpers::extendedModulo (millisSinceEpoch, 1000); }
|
||||
|
||||
int Time::getHoursInAmPmFormat() const noexcept
|
||||
{
|
||||
const int hours = getHours();
|
||||
|
||||
if (hours == 0) return 12;
|
||||
if (hours <= 12) return hours;
|
||||
|
||||
return hours - 12;
|
||||
}
|
||||
|
||||
bool Time::isAfternoon() const noexcept
|
||||
{
|
||||
return getHours() >= 12;
|
||||
}
|
||||
|
||||
bool Time::isDaylightSavingTime() const noexcept
|
||||
{
|
||||
return TimeHelpers::millisToLocal (millisSinceEpoch).tm_isdst != 0;
|
||||
}
|
||||
|
||||
String Time::getTimeZone() const noexcept
|
||||
{
|
||||
String zone[2];
|
||||
|
||||
#if BEAST_WINDOWS
|
||||
_tzset();
|
||||
|
||||
#ifdef _INC_TIME_INL
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
char name[128] = { 0 };
|
||||
size_t length;
|
||||
_get_tzname (&length, name, 127, i);
|
||||
zone[i] = name;
|
||||
}
|
||||
#else
|
||||
const char** const zonePtr = (const char**) _tzname;
|
||||
zone[0] = zonePtr[0];
|
||||
zone[1] = zonePtr[1];
|
||||
#endif
|
||||
#else
|
||||
tzset();
|
||||
const char** const zonePtr = (const char**) tzname;
|
||||
zone[0] = zonePtr[0];
|
||||
zone[1] = zonePtr[1];
|
||||
#endif
|
||||
|
||||
if (isDaylightSavingTime())
|
||||
{
|
||||
zone[0] = zone[1];
|
||||
|
||||
if (zone[0].length() > 3
|
||||
&& zone[0].containsIgnoreCase ("daylight")
|
||||
&& zone[0].contains ("GMT"))
|
||||
zone[0] = "BST";
|
||||
}
|
||||
|
||||
return zone[0].substring (0, 3);
|
||||
}
|
||||
|
||||
String Time::getMonthName (const bool threeLetterVersion) const
|
||||
{
|
||||
return getMonthName (getMonth(), threeLetterVersion);
|
||||
}
|
||||
|
||||
String Time::getWeekdayName (const bool threeLetterVersion) const
|
||||
{
|
||||
return getWeekdayName (getDayOfWeek(), threeLetterVersion);
|
||||
}
|
||||
|
||||
String Time::getMonthName (int monthNumber, const bool threeLetterVersion)
|
||||
{
|
||||
const char* const shortMonthNames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
const char* const longMonthNames[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
|
||||
|
||||
monthNumber %= 12;
|
||||
|
||||
return threeLetterVersion ? shortMonthNames [monthNumber]
|
||||
: longMonthNames [monthNumber];
|
||||
}
|
||||
|
||||
String Time::getWeekdayName (int day, const bool threeLetterVersion)
|
||||
{
|
||||
const char* const shortDayNames[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||
const char* const longDayNames[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
|
||||
|
||||
day %= 7;
|
||||
|
||||
return threeLetterVersion ? shortDayNames [day]
|
||||
: longDayNames [day];
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
Time& Time::operator+= (RelativeTime delta) { millisSinceEpoch += delta.inMilliseconds(); return *this; }
|
||||
Time& Time::operator-= (RelativeTime delta) { millisSinceEpoch -= delta.inMilliseconds(); return *this; }
|
||||
|
||||
Time operator+ (Time time, RelativeTime delta) { Time t (time); return t += delta; }
|
||||
Time operator- (Time time, RelativeTime delta) { Time t (time); return t -= delta; }
|
||||
Time operator+ (RelativeTime delta, Time time) { Time t (time); return t += delta; }
|
||||
const RelativeTime operator- (Time time1, Time time2) { return RelativeTime::milliseconds (time1.toMilliseconds() - time2.toMilliseconds()); }
|
||||
|
||||
bool operator== (Time time1, Time time2) { return time1.toMilliseconds() == time2.toMilliseconds(); }
|
||||
bool operator!= (Time time1, Time time2) { return time1.toMilliseconds() != time2.toMilliseconds(); }
|
||||
bool operator< (Time time1, Time time2) { return time1.toMilliseconds() < time2.toMilliseconds(); }
|
||||
bool operator> (Time time1, Time time2) { return time1.toMilliseconds() > time2.toMilliseconds(); }
|
||||
bool operator<= (Time time1, Time time2) { return time1.toMilliseconds() <= time2.toMilliseconds(); }
|
||||
bool operator>= (Time time1, Time time2) { return time1.toMilliseconds() >= time2.toMilliseconds(); }
|
||||
|
||||
} // beast
|
||||
|
||||
@@ -24,311 +24,11 @@
|
||||
#ifndef BEAST_MODULE_CORE_TIME_TIME_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_TIME_TIME_H_INCLUDED
|
||||
|
||||
#include <beast/chrono/RelativeTime.h>
|
||||
#include <cstdint>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Holds an absolute date and time.
|
||||
|
||||
Internally, the time is stored at millisecond precision.
|
||||
|
||||
@see RelativeTime
|
||||
*/
|
||||
class Time
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a Time object.
|
||||
|
||||
This default constructor creates a time of 1st January 1970, (which is
|
||||
represented internally as 0ms).
|
||||
|
||||
To create a time object representing the current time, use getCurrentTime().
|
||||
|
||||
@see getCurrentTime
|
||||
*/
|
||||
Time() noexcept;
|
||||
|
||||
/** Creates a time based on a number of milliseconds.
|
||||
|
||||
The internal millisecond count is set to 0 (1st January 1970). To create a
|
||||
time object set to the current time, use getCurrentTime().
|
||||
|
||||
@param millisecondsSinceEpoch the number of milliseconds since the unix
|
||||
'epoch' (midnight Jan 1st 1970).
|
||||
@see getCurrentTime, currentTimeMillis
|
||||
*/
|
||||
explicit Time (std::int64_t millisecondsSinceEpoch) noexcept;
|
||||
|
||||
/** Creates a time from a set of date components.
|
||||
|
||||
The timezone is assumed to be whatever the system is using as its locale.
|
||||
|
||||
@param year the year, in 4-digit format, e.g. 2004
|
||||
@param month the month, in the range 0 to 11
|
||||
@param day the day of the month, in the range 1 to 31
|
||||
@param hours hours in 24-hour clock format, 0 to 23
|
||||
@param minutes minutes 0 to 59
|
||||
@param seconds seconds 0 to 59
|
||||
@param milliseconds milliseconds 0 to 999
|
||||
@param useLocalTime if true, encode using the current machine's local time; if
|
||||
false, it will always work in GMT.
|
||||
*/
|
||||
Time (int year,
|
||||
int month,
|
||||
int day,
|
||||
int hours,
|
||||
int minutes,
|
||||
int seconds = 0,
|
||||
int milliseconds = 0,
|
||||
bool useLocalTime = true) noexcept;
|
||||
|
||||
/** Creates a copy of another Time object. */
|
||||
Time (const Time& other) noexcept;
|
||||
|
||||
/** Destructor. */
|
||||
~Time() noexcept;
|
||||
|
||||
/** Copies this time from another one. */
|
||||
Time& operator= (const Time& other) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a Time object that is set to the current system time.
|
||||
|
||||
@see currentTimeMillis
|
||||
*/
|
||||
static Time getCurrentTime() noexcept;
|
||||
|
||||
/** Returns `true` if this object represents "no time", or NULL.
|
||||
Internally we check for milliseconds since Epoch equal to zero.
|
||||
*/
|
||||
/** @{ */
|
||||
bool isNull () const noexcept
|
||||
{
|
||||
return millisSinceEpoch == 0;
|
||||
}
|
||||
|
||||
bool isNotNull () const noexcept
|
||||
{
|
||||
return millisSinceEpoch != 0;
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** Returns the time as a number of milliseconds.
|
||||
|
||||
@returns the number of milliseconds this Time object represents, since
|
||||
midnight jan 1st 1970.
|
||||
@see getMilliseconds
|
||||
*/
|
||||
std::int64_t toMilliseconds() const noexcept { return millisSinceEpoch; }
|
||||
|
||||
/** Returns the year.
|
||||
|
||||
A 4-digit format is used, e.g. 2004.
|
||||
*/
|
||||
int getYear() const noexcept;
|
||||
|
||||
/** Returns the number of the month.
|
||||
|
||||
The value returned is in the range 0 to 11.
|
||||
@see getMonthName
|
||||
*/
|
||||
int getMonth() const noexcept;
|
||||
|
||||
/** Returns the name of the month.
|
||||
|
||||
@param threeLetterVersion if true, it'll be a 3-letter abbreviation, e.g. "Jan"; if false
|
||||
it'll return the long form, e.g. "January"
|
||||
@see getMonth
|
||||
*/
|
||||
String getMonthName (bool threeLetterVersion) const;
|
||||
|
||||
/** Returns the day of the month.
|
||||
The value returned is in the range 1 to 31.
|
||||
*/
|
||||
int getDayOfMonth() const noexcept;
|
||||
|
||||
/** Returns the number of the day of the week.
|
||||
The value returned is in the range 0 to 6 (0 = sunday, 1 = monday, etc).
|
||||
*/
|
||||
int getDayOfWeek() const noexcept;
|
||||
|
||||
/** Returns the number of the day of the year.
|
||||
The value returned is in the range 0 to 365.
|
||||
*/
|
||||
int getDayOfYear() const noexcept;
|
||||
|
||||
/** Returns the name of the weekday.
|
||||
|
||||
@param threeLetterVersion if true, it'll return a 3-letter abbreviation, e.g. "Tue"; if
|
||||
false, it'll return the full version, e.g. "Tuesday".
|
||||
*/
|
||||
String getWeekdayName (bool threeLetterVersion) const;
|
||||
|
||||
/** Returns the number of hours since midnight.
|
||||
|
||||
This is in 24-hour clock format, in the range 0 to 23.
|
||||
|
||||
@see getHoursInAmPmFormat, isAfternoon
|
||||
*/
|
||||
int getHours() const noexcept;
|
||||
|
||||
/** Returns true if the time is in the afternoon.
|
||||
|
||||
So it returns true for "PM", false for "AM".
|
||||
|
||||
@see getHoursInAmPmFormat, getHours
|
||||
*/
|
||||
bool isAfternoon() const noexcept;
|
||||
|
||||
/** Returns the hours in 12-hour clock format.
|
||||
|
||||
This will return a value 1 to 12 - use isAfternoon() to find out
|
||||
whether this is in the afternoon or morning.
|
||||
|
||||
@see getHours, isAfternoon
|
||||
*/
|
||||
int getHoursInAmPmFormat() const noexcept;
|
||||
|
||||
/** Returns the number of minutes, 0 to 59. */
|
||||
int getMinutes() const noexcept;
|
||||
|
||||
/** Returns the number of seconds, 0 to 59. */
|
||||
int getSeconds() const noexcept;
|
||||
|
||||
/** Returns the number of milliseconds, 0 to 999.
|
||||
|
||||
Unlike toMilliseconds(), this just returns the position within the
|
||||
current second rather than the total number since the epoch.
|
||||
|
||||
@see toMilliseconds
|
||||
*/
|
||||
int getMilliseconds() const noexcept;
|
||||
|
||||
/** Returns true if the local timezone uses a daylight saving correction. */
|
||||
bool isDaylightSavingTime() const noexcept;
|
||||
|
||||
/** Returns a 3-character string to indicate the local timezone. */
|
||||
String getTimeZone() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Quick way of getting a string version of a date and time.
|
||||
|
||||
For a more powerful way of formatting the date and time, see the formatted() method.
|
||||
|
||||
@param includeDate whether to include the date in the string
|
||||
@param includeTime whether to include the time in the string
|
||||
@param includeSeconds if the time is being included, this provides an option not to include
|
||||
the seconds in it
|
||||
@param use24HourClock if the time is being included, sets whether to use am/pm or 24
|
||||
hour notation.
|
||||
@see formatted
|
||||
*/
|
||||
String toString (bool includeDate,
|
||||
bool includeTime,
|
||||
bool includeSeconds = true,
|
||||
bool use24HourClock = false) const noexcept;
|
||||
|
||||
/** Converts this date/time to a string with a user-defined format.
|
||||
|
||||
This uses the C strftime() function to format this time as a string. To save you
|
||||
looking it up, these are the escape codes that strftime uses (other codes might
|
||||
work on some platforms and not others, but these are the common ones):
|
||||
|
||||
%a is replaced by the locale's abbreviated weekday name.
|
||||
%A is replaced by the locale's full weekday name.
|
||||
%b is replaced by the locale's abbreviated month name.
|
||||
%B is replaced by the locale's full month name.
|
||||
%c is replaced by the locale's appropriate date and time representation.
|
||||
%d is replaced by the day of the month as a decimal number [01,31].
|
||||
%H is replaced by the hour (24-hour clock) as a decimal number [00,23].
|
||||
%I is replaced by the hour (12-hour clock) as a decimal number [01,12].
|
||||
%j is replaced by the day of the year as a decimal number [001,366].
|
||||
%m is replaced by the month as a decimal number [01,12].
|
||||
%M is replaced by the minute as a decimal number [00,59].
|
||||
%p is replaced by the locale's equivalent of either a.m. or p.m.
|
||||
%S is replaced by the second as a decimal number [00,61].
|
||||
%U is replaced by the week number of the year (Sunday as the first day of the week) as a decimal number [00,53].
|
||||
%w is replaced by the weekday as a decimal number [0,6], with 0 representing Sunday.
|
||||
%W is replaced by the week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0.
|
||||
%x is replaced by the locale's appropriate date representation.
|
||||
%X is replaced by the locale's appropriate time representation.
|
||||
%y is replaced by the year without century as a decimal number [00,99].
|
||||
%Y is replaced by the year with century as a decimal number.
|
||||
%Z is replaced by the timezone name or abbreviation, or by no bytes if no timezone information exists.
|
||||
%% is replaced by %.
|
||||
|
||||
@see toString
|
||||
*/
|
||||
String formatted (const String& format) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Adds a RelativeTime to this time. */
|
||||
Time& operator+= (RelativeTime delta);
|
||||
/** Subtracts a RelativeTime from this time. */
|
||||
Time& operator-= (RelativeTime delta);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the name of a day of the week.
|
||||
|
||||
@param dayNumber the day, 0 to 6 (0 = sunday, 1 = monday, etc)
|
||||
@param threeLetterVersion if true, it'll return a 3-letter abbreviation, e.g. "Tue"; if
|
||||
false, it'll return the full version, e.g. "Tuesday".
|
||||
*/
|
||||
static String getWeekdayName (int dayNumber,
|
||||
bool threeLetterVersion);
|
||||
|
||||
/** Returns the name of one of the months.
|
||||
|
||||
@param monthNumber the month, 0 to 11
|
||||
@param threeLetterVersion if true, it'll be a 3-letter abbreviation, e.g. "Jan"; if false
|
||||
it'll return the long form, e.g. "January"
|
||||
*/
|
||||
static String getMonthName (int monthNumber,
|
||||
bool threeLetterVersion);
|
||||
|
||||
//==============================================================================
|
||||
// Static methods for getting system timers directly..
|
||||
|
||||
/** Returns the current system time.
|
||||
|
||||
Returns the number of milliseconds since midnight jan 1st 1970.
|
||||
|
||||
Should be accurate to within a few millisecs, depending on platform,
|
||||
hardware, etc.
|
||||
*/
|
||||
static std::int64_t currentTimeMillis() noexcept;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
std::int64_t millisSinceEpoch;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Adds a RelativeTime to a Time. */
|
||||
Time operator+ (Time time, RelativeTime delta);
|
||||
/** Adds a RelativeTime to a Time. */
|
||||
Time operator+ (RelativeTime delta, Time time);
|
||||
|
||||
/** Subtracts a RelativeTime from a Time. */
|
||||
Time operator- (Time time, RelativeTime delta);
|
||||
/** Returns the relative time difference between two times. */
|
||||
const RelativeTime operator- (Time time1, Time time2);
|
||||
|
||||
/** Compares two Time objects. */
|
||||
bool operator== (Time time1, Time time2);
|
||||
/** Compares two Time objects. */
|
||||
bool operator!= (Time time1, Time time2);
|
||||
/** Compares two Time objects. */
|
||||
bool operator< (Time time1, Time time2);
|
||||
/** Compares two Time objects. */
|
||||
bool operator<= (Time time1, Time time2);
|
||||
/** Compares two Time objects. */
|
||||
bool operator> (Time time1, Time time2);
|
||||
/** Compares two Time objects. */
|
||||
bool operator>= (Time time1, Time time2);
|
||||
std::int64_t currentTimeMillis();
|
||||
|
||||
} // beast
|
||||
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_NET_DYNAMICBUFFER_H_INCLUDED
|
||||
#define BEAST_NET_DYNAMICBUFFER_H_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** Disjoint, but efficient buffer storage for network operations.
|
||||
This is designed to not require asio in order to compile.
|
||||
*/
|
||||
class DynamicBuffer
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
defaultBlocksize = 32 * 1024
|
||||
};
|
||||
|
||||
using size_type = std::size_t;
|
||||
|
||||
/** Create the dynamic buffer with the specified block size. */
|
||||
explicit DynamicBuffer (size_type blocksize = defaultBlocksize);
|
||||
|
||||
DynamicBuffer (DynamicBuffer const& other);
|
||||
|
||||
~DynamicBuffer ();
|
||||
|
||||
DynamicBuffer& operator= (DynamicBuffer const& other);
|
||||
|
||||
/** Swap the contents of this buffer with another.
|
||||
This is the preferred way to transfer ownership.
|
||||
*/
|
||||
void swapWith (DynamicBuffer& other);
|
||||
|
||||
/** Returns the size of the input sequence. */
|
||||
size_type size () const;
|
||||
|
||||
/** Returns a buffer to the input sequence.
|
||||
ConstBufferType must be constructible with this signature:
|
||||
ConstBufferType (void const* buffer, size_type bytes);
|
||||
*/
|
||||
template <typename ConstBufferType>
|
||||
std::vector <ConstBufferType>
|
||||
data () const
|
||||
{
|
||||
std::vector <ConstBufferType> buffers;
|
||||
buffers.reserve (m_buffers.size());
|
||||
size_type amount (m_size);
|
||||
for (typename Buffers::const_iterator iter (m_buffers.begin());
|
||||
amount > 0 && iter != m_buffers.end(); ++iter)
|
||||
{
|
||||
size_type const n (std::min (amount, m_blocksize));
|
||||
buffers.push_back (ConstBufferType (*iter, n));
|
||||
amount -= n;
|
||||
}
|
||||
return buffers;
|
||||
}
|
||||
|
||||
/** Reserve space in the output sequence.
|
||||
This also returns a buffer suitable for writing.
|
||||
MutableBufferType must be constructible with this signature:
|
||||
MutableBufferType (void* buffer, size_type bytes);
|
||||
*/
|
||||
template <typename MutableBufferType>
|
||||
std::vector <MutableBufferType>
|
||||
prepare (size_type amount)
|
||||
{
|
||||
std::vector <MutableBufferType> buffers;
|
||||
buffers.reserve (m_buffers.size());
|
||||
reserve (amount);
|
||||
size_type offset (m_size % m_blocksize);
|
||||
for (Buffers::iterator iter = m_buffers.begin () + (m_size / m_blocksize);
|
||||
amount > 0 && iter != m_buffers.end (); ++iter)
|
||||
{
|
||||
size_type const n (std::min (amount, m_blocksize - offset));
|
||||
buffers.push_back (MutableBufferType (
|
||||
((static_cast <char*> (*iter)) + offset), n));
|
||||
amount -= n;
|
||||
offset = 0;
|
||||
}
|
||||
return buffers;
|
||||
}
|
||||
|
||||
/** Reserve space in the output sequence. */
|
||||
void reserve (size_type n);
|
||||
|
||||
/** Move bytes from the output to the input sequence. */
|
||||
void commit (size_type n);
|
||||
|
||||
/** Release memory while preserving the input sequence. */
|
||||
void shrink_to_fit ();
|
||||
|
||||
/** Convert the entire buffer into a single string.
|
||||
This is mostly for diagnostics, it defeats the purpose of the class!
|
||||
*/
|
||||
std::string to_string () const;
|
||||
|
||||
private:
|
||||
using Buffers = std::vector <void*>;
|
||||
|
||||
size_type m_blocksize;
|
||||
size_type m_size;
|
||||
Buffers m_buffers;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include <beast/Config.h>
|
||||
|
||||
#include <beast/net/impl/DynamicBuffer.cpp>
|
||||
#include <beast/net/impl/IPAddressV4.cpp>
|
||||
#include <beast/net/impl/IPAddressV6.cpp>
|
||||
#include <beast/net/impl/IPEndpoint.cpp>
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include "../../BeastConfig.h"
|
||||
#endif
|
||||
|
||||
#include <beast/net/DynamicBuffer.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
namespace beast {
|
||||
|
||||
DynamicBuffer::DynamicBuffer (size_type blocksize)
|
||||
: m_blocksize (blocksize)
|
||||
, m_size (0)
|
||||
{
|
||||
}
|
||||
|
||||
DynamicBuffer::~DynamicBuffer ()
|
||||
{
|
||||
for (Buffers::iterator iter (m_buffers.begin());
|
||||
iter != m_buffers.end(); ++iter)
|
||||
free (*iter);
|
||||
}
|
||||
|
||||
void DynamicBuffer::swapWith (DynamicBuffer& other)
|
||||
{
|
||||
std::swap (m_blocksize, other.m_blocksize);
|
||||
std::swap (m_size, other.m_size);
|
||||
m_buffers.swap (other.m_buffers);
|
||||
}
|
||||
|
||||
void DynamicBuffer::commit (size_type n)
|
||||
{
|
||||
m_size += n;
|
||||
bassert (m_size <= m_buffers.size () * m_blocksize);
|
||||
}
|
||||
|
||||
DynamicBuffer::size_type DynamicBuffer::size () const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
void DynamicBuffer::reserve (size_type n)
|
||||
{
|
||||
size_type count ((m_size + n + m_blocksize - 1) / m_blocksize);
|
||||
if (count > m_buffers.size ())
|
||||
for (count -= m_buffers.size (); count-- > 0;)
|
||||
m_buffers.push_back (malloc (m_blocksize));
|
||||
}
|
||||
|
||||
void DynamicBuffer::shrink_to_fit ()
|
||||
{
|
||||
size_type const count ((m_size + m_blocksize - 1) / m_blocksize);
|
||||
while (m_buffers.size () > count)
|
||||
{
|
||||
free (m_buffers.back ());
|
||||
m_buffers.erase (m_buffers.end () - 1);
|
||||
}
|
||||
}
|
||||
|
||||
std::string DynamicBuffer::to_string () const
|
||||
{
|
||||
std::string (s);
|
||||
s.reserve (m_size);
|
||||
std::size_t amount (m_size);
|
||||
for (Buffers::const_iterator iter (m_buffers.begin());
|
||||
amount > 0 && iter != m_buffers.end(); ++iter)
|
||||
{
|
||||
char const* p (static_cast <char const*> (*iter));
|
||||
size_type const n (std::min (amount, m_blocksize));
|
||||
s.append (p, p + n);
|
||||
amount -= n;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include <beast/nudb/tests/common.h>
|
||||
#include <beast/module/core/diagnostic/UnitTestUtilities.h>
|
||||
#include <beast/module/core/files/File.h>
|
||||
#include <beast/xor_shift_engine.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <cmath>
|
||||
@@ -98,10 +97,9 @@ public:
|
||||
};
|
||||
|
||||
testcase (abort_on_fail);
|
||||
path_type const path =
|
||||
beast::UnitTestUtilities::TempDirectory(
|
||||
"nudb").getFullPathName().toStdString();
|
||||
do_test (N, path);
|
||||
|
||||
beast::UnitTestUtilities::TempDirectory tempDir;
|
||||
do_test (N, tempDir.path());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/nudb/tests/common.h>
|
||||
#include <beast/module/core/files/File.h>
|
||||
#include <beast/xor_shift_engine.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <cmath>
|
||||
@@ -116,9 +115,10 @@ public:
|
||||
test_recover (float load_factor, std::size_t count)
|
||||
{
|
||||
testcase << count << " inserts";
|
||||
path_type const path =
|
||||
beast::UnitTestUtilities::TempDirectory(
|
||||
"nudb").getFullPathName().toStdString();
|
||||
|
||||
beast::UnitTestUtilities::TempDirectory tempDir;
|
||||
|
||||
auto const path = tempDir.path();
|
||||
for (std::size_t n = 1;;++n)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include <BeastConfig.h>
|
||||
#include <beast/nudb/tests/common.h>
|
||||
#include <beast/module/core/diagnostic/UnitTestUtilities.h>
|
||||
#include <beast/module/core/files/File.h>
|
||||
#include <beast/xor_shift_engine.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <cmath>
|
||||
@@ -46,12 +45,11 @@ public:
|
||||
std::size_t block_size, float load_factor)
|
||||
{
|
||||
testcase (abort_on_fail);
|
||||
std::string const path =
|
||||
beast::UnitTestUtilities::TempDirectory(
|
||||
"test_db").getFullPathName().toStdString();
|
||||
auto const dp = path + ".dat";
|
||||
auto const kp = path + ".key";
|
||||
auto const lp = path + ".log";
|
||||
beast::UnitTestUtilities::TempDirectory tempDir;
|
||||
|
||||
auto const dp = tempDir.file ("nudb.dat");
|
||||
auto const kp = tempDir.file ("nudb.key");
|
||||
auto const lp = tempDir.file ("nudb.log");
|
||||
Sequence seq;
|
||||
test_api::store db;
|
||||
try
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#define BEAST_SMART_PTR_SHAREDOBJECT_H_INCLUDED
|
||||
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
|
||||
#include <beast/Config.h>
|
||||
|
||||
@@ -78,7 +79,7 @@ public:
|
||||
/** Decreases the object's reference count. */
|
||||
void decReferenceCount () const
|
||||
{
|
||||
bassert (getReferenceCount() > 0);
|
||||
assert (getReferenceCount() > 0);
|
||||
if (--refCount == 0)
|
||||
destroy ();
|
||||
}
|
||||
@@ -104,7 +105,7 @@ protected:
|
||||
virtual ~SharedObject()
|
||||
{
|
||||
// it's dangerous to delete an object that's still referenced by something else!
|
||||
bassert (getReferenceCount() == 0);
|
||||
assert (getReferenceCount() == 0);
|
||||
}
|
||||
|
||||
/** Destroy the object.
|
||||
|
||||
@@ -1,392 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_STRINGS_CHARPOINTER_ASCII_H_INCLUDED
|
||||
#define BEAST_STRINGS_CHARPOINTER_ASCII_H_INCLUDED
|
||||
|
||||
#include <beast/Config.h>
|
||||
|
||||
#include <beast/strings/CharacterFunctions.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Wraps a pointer to a null-terminated ASCII character string, and provides
|
||||
various methods to operate on the data.
|
||||
|
||||
A valid ASCII string is assumed to not contain any characters above 127.
|
||||
|
||||
@see CharPointer_UTF8, CharPointer_UTF16, CharPointer_UTF32
|
||||
*/
|
||||
class CharPointer_ASCII
|
||||
{
|
||||
public:
|
||||
using CharType = char;
|
||||
|
||||
inline explicit CharPointer_ASCII (const CharType* const rawPointer) noexcept
|
||||
: data (const_cast <CharType*> (rawPointer))
|
||||
{
|
||||
}
|
||||
|
||||
inline CharPointer_ASCII (const CharPointer_ASCII& other) noexcept
|
||||
: data (other.data)
|
||||
{
|
||||
}
|
||||
|
||||
inline CharPointer_ASCII operator= (const CharPointer_ASCII other) noexcept
|
||||
{
|
||||
data = other.data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CharPointer_ASCII operator= (const CharType* text) noexcept
|
||||
{
|
||||
data = const_cast <CharType*> (text);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** This is a pointer comparison, it doesn't compare the actual text. */
|
||||
inline bool operator== (CharPointer_ASCII other) const noexcept { return data == other.data; }
|
||||
inline bool operator!= (CharPointer_ASCII other) const noexcept { return data != other.data; }
|
||||
inline bool operator<= (CharPointer_ASCII other) const noexcept { return data <= other.data; }
|
||||
inline bool operator< (CharPointer_ASCII other) const noexcept { return data < other.data; }
|
||||
inline bool operator>= (CharPointer_ASCII other) const noexcept { return data >= other.data; }
|
||||
inline bool operator> (CharPointer_ASCII other) const noexcept { return data > other.data; }
|
||||
|
||||
/** Returns the address that this pointer is pointing to. */
|
||||
inline CharType* getAddress() const noexcept { return data; }
|
||||
|
||||
/** Returns the address that this pointer is pointing to. */
|
||||
inline operator const CharType*() const noexcept { return data; }
|
||||
|
||||
/** Returns true if this pointer is pointing to a null character. */
|
||||
inline bool isEmpty() const noexcept { return *data == 0; }
|
||||
|
||||
/** Returns the unicode character that this pointer is pointing to. */
|
||||
inline beast_wchar operator*() const noexcept { return (beast_wchar) (std::uint8_t) *data; }
|
||||
|
||||
/** Moves this pointer along to the next character in the string. */
|
||||
inline CharPointer_ASCII operator++() noexcept
|
||||
{
|
||||
++data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Moves this pointer to the previous character in the string. */
|
||||
inline CharPointer_ASCII operator--() noexcept
|
||||
{
|
||||
--data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Returns the character that this pointer is currently pointing to, and then
|
||||
advances the pointer to point to the next character. */
|
||||
inline beast_wchar getAndAdvance() noexcept { return (beast_wchar) (std::uint8_t) *data++; }
|
||||
|
||||
/** Moves this pointer along to the next character in the string. */
|
||||
CharPointer_ASCII operator++ (int) noexcept
|
||||
{
|
||||
CharPointer_ASCII temp (*this);
|
||||
++data;
|
||||
return temp;
|
||||
}
|
||||
|
||||
/** Moves this pointer forwards by the specified number of characters. */
|
||||
inline void operator+= (const int numToSkip) noexcept
|
||||
{
|
||||
data += numToSkip;
|
||||
}
|
||||
|
||||
inline void operator-= (const int numToSkip) noexcept
|
||||
{
|
||||
data -= numToSkip;
|
||||
}
|
||||
|
||||
/** Returns the character at a given character index from the start of the string. */
|
||||
inline beast_wchar operator[] (const int characterIndex) const noexcept
|
||||
{
|
||||
return (beast_wchar) (unsigned char) data [characterIndex];
|
||||
}
|
||||
|
||||
/** Returns a pointer which is moved forwards from this one by the specified number of characters. */
|
||||
CharPointer_ASCII operator+ (const int numToSkip) const noexcept
|
||||
{
|
||||
return CharPointer_ASCII (data + numToSkip);
|
||||
}
|
||||
|
||||
/** Returns a pointer which is moved backwards from this one by the specified number of characters. */
|
||||
CharPointer_ASCII operator- (const int numToSkip) const noexcept
|
||||
{
|
||||
return CharPointer_ASCII (data - numToSkip);
|
||||
}
|
||||
|
||||
/** Writes a unicode character to this string, and advances this pointer to point to the next position. */
|
||||
inline void write (const beast_wchar charToWrite) noexcept
|
||||
{
|
||||
*data++ = (char) charToWrite;
|
||||
}
|
||||
|
||||
inline void replaceChar (const beast_wchar newChar) noexcept
|
||||
{
|
||||
*data = (char) newChar;
|
||||
}
|
||||
|
||||
/** Writes a null character to this string (leaving the pointer's position unchanged). */
|
||||
inline void writeNull() const noexcept
|
||||
{
|
||||
*data = 0;
|
||||
}
|
||||
|
||||
/** Returns the number of characters in this string. */
|
||||
size_t length() const noexcept
|
||||
{
|
||||
return (size_t) strlen (data);
|
||||
}
|
||||
|
||||
/** Returns the number of characters in this string, or the given value, whichever is lower. */
|
||||
size_t lengthUpTo (const size_t maxCharsToCount) const noexcept
|
||||
{
|
||||
return CharacterFunctions::lengthUpTo (*this, maxCharsToCount);
|
||||
}
|
||||
|
||||
/** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */
|
||||
size_t lengthUpTo (const CharPointer_ASCII end) const noexcept
|
||||
{
|
||||
return CharacterFunctions::lengthUpTo (*this, end);
|
||||
}
|
||||
|
||||
/** Returns the number of bytes that are used to represent this string.
|
||||
This includes the terminating null character.
|
||||
*/
|
||||
size_t sizeInBytes() const noexcept
|
||||
{
|
||||
return length() + 1;
|
||||
}
|
||||
|
||||
/** Returns the number of bytes that would be needed to represent the given
|
||||
unicode character in this encoding format.
|
||||
*/
|
||||
static inline size_t getBytesRequiredFor (const beast_wchar) noexcept
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Returns the number of bytes that would be needed to represent the given
|
||||
string in this encoding format.
|
||||
The value returned does NOT include the terminating null character.
|
||||
*/
|
||||
template <class CharPointer>
|
||||
static size_t getBytesRequiredFor (const CharPointer text) noexcept
|
||||
{
|
||||
return text.length();
|
||||
}
|
||||
|
||||
/** Returns a pointer to the null character that terminates this string. */
|
||||
CharPointer_ASCII findTerminatingNull() const noexcept
|
||||
{
|
||||
return CharPointer_ASCII (data + length());
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes. */
|
||||
template <typename CharPointer>
|
||||
void writeAll (const CharPointer src) noexcept
|
||||
{
|
||||
CharacterFunctions::copyAll (*this, src);
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes. */
|
||||
void writeAll (const CharPointer_ASCII src) noexcept
|
||||
{
|
||||
strcpy (data, src.data);
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes.
|
||||
The maxDestBytes parameter specifies the maximum number of bytes that can be written
|
||||
to the destination buffer before stopping.
|
||||
*/
|
||||
template <typename CharPointer>
|
||||
size_t writeWithDestByteLimit (const CharPointer src, const size_t maxDestBytes) noexcept
|
||||
{
|
||||
return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes);
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes.
|
||||
The maxChars parameter specifies the maximum number of characters that can be
|
||||
written to the destination buffer before stopping (including the terminating null).
|
||||
*/
|
||||
template <typename CharPointer>
|
||||
void writeWithCharLimit (const CharPointer src, const int maxChars) noexcept
|
||||
{
|
||||
CharacterFunctions::copyWithCharLimit (*this, src, maxChars);
|
||||
}
|
||||
|
||||
/** Compares this string with another one. */
|
||||
template <typename CharPointer>
|
||||
int compare (const CharPointer other) const noexcept
|
||||
{
|
||||
return CharacterFunctions::compare (*this, other);
|
||||
}
|
||||
|
||||
/** Compares this string with another one. */
|
||||
int compare (const CharPointer_ASCII other) const noexcept
|
||||
{
|
||||
return strcmp (data, other.data);
|
||||
}
|
||||
|
||||
/** Compares this string with another one, up to a specified number of characters. */
|
||||
template <typename CharPointer>
|
||||
int compareUpTo (const CharPointer other, const int maxChars) const noexcept
|
||||
{
|
||||
return CharacterFunctions::compareUpTo (*this, other, maxChars);
|
||||
}
|
||||
|
||||
/** Compares this string with another one, up to a specified number of characters. */
|
||||
int compareUpTo (const CharPointer_ASCII other, const int maxChars) const noexcept
|
||||
{
|
||||
return strncmp (data, other.data, (size_t) maxChars);
|
||||
}
|
||||
|
||||
/** Compares this string with another one. */
|
||||
template <typename CharPointer>
|
||||
int compareIgnoreCase (const CharPointer other) const
|
||||
{
|
||||
return CharacterFunctions::compareIgnoreCase (*this, other);
|
||||
}
|
||||
|
||||
int compareIgnoreCase (const CharPointer_ASCII other) const
|
||||
{
|
||||
#if BEAST_WINDOWS
|
||||
return stricmp (data, other.data);
|
||||
#else
|
||||
return strcasecmp (data, other.data);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Compares this string with another one, up to a specified number of characters. */
|
||||
template <typename CharPointer>
|
||||
int compareIgnoreCaseUpTo (const CharPointer other, const int maxChars) const noexcept
|
||||
{
|
||||
return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars);
|
||||
}
|
||||
|
||||
/** Returns the character index of a substring, or -1 if it isn't found. */
|
||||
template <typename CharPointer>
|
||||
int indexOf (const CharPointer stringToFind) const noexcept
|
||||
{
|
||||
return CharacterFunctions::indexOf (*this, stringToFind);
|
||||
}
|
||||
|
||||
/** Returns the character index of a unicode character, or -1 if it isn't found. */
|
||||
int indexOf (const beast_wchar charToFind) const noexcept
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (data[i] != 0)
|
||||
{
|
||||
if (data[i] == (char) charToFind)
|
||||
return i;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Returns the character index of a unicode character, or -1 if it isn't found. */
|
||||
int indexOf (const beast_wchar charToFind, const bool ignoreCase) const noexcept
|
||||
{
|
||||
return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind)
|
||||
: CharacterFunctions::indexOfChar (*this, charToFind);
|
||||
}
|
||||
|
||||
/** Returns true if the first character of this string is whitespace. */
|
||||
bool isWhitespace() const { return CharacterFunctions::isWhitespace (*data) != 0; }
|
||||
/** Returns true if the first character of this string is a digit. */
|
||||
bool isDigit() const { return CharacterFunctions::isDigit (*data) != 0; }
|
||||
/** Returns true if the first character of this string is a letter. */
|
||||
bool isLetter() const { return CharacterFunctions::isLetter (*data) != 0; }
|
||||
/** Returns true if the first character of this string is a letter or digit. */
|
||||
bool isLetterOrDigit() const { return CharacterFunctions::isLetterOrDigit (*data) != 0; }
|
||||
/** Returns true if the first character of this string is upper-case. */
|
||||
bool isUpperCase() const { return CharacterFunctions::isUpperCase ((beast_wchar) (std::uint8_t) *data) != 0; }
|
||||
/** Returns true if the first character of this string is lower-case. */
|
||||
bool isLowerCase() const { return CharacterFunctions::isLowerCase ((beast_wchar) (std::uint8_t) *data) != 0; }
|
||||
|
||||
/** Returns an upper-case version of the first character of this string. */
|
||||
beast_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase ((beast_wchar) (std::uint8_t) *data); }
|
||||
/** Returns a lower-case version of the first character of this string. */
|
||||
beast_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase ((beast_wchar) (std::uint8_t) *data); }
|
||||
|
||||
/** Parses this string as a 32-bit integer. */
|
||||
int getIntValue32() const noexcept { return atoi (data); }
|
||||
|
||||
/** Parses this string as a 64-bit integer. */
|
||||
std::int64_t getIntValue64() const noexcept
|
||||
{
|
||||
#if BEAST_LINUX || BEAST_ANDROID
|
||||
return atoll (data);
|
||||
#elif BEAST_WINDOWS
|
||||
return _atoi64 (data);
|
||||
#else
|
||||
return CharacterFunctions::getIntValue <std::int64_t, CharPointer_ASCII> (*this);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Parses this string as a floating point double. */
|
||||
double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); }
|
||||
|
||||
/** Returns the first non-whitespace character in the string. */
|
||||
CharPointer_ASCII findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); }
|
||||
|
||||
/** Returns true if the given unicode character can be represented in this encoding. */
|
||||
static bool canRepresent (beast_wchar character) noexcept
|
||||
{
|
||||
return ((unsigned int) character) < (unsigned int) 128;
|
||||
}
|
||||
|
||||
/** Returns true if this data contains a valid string in this encoding. */
|
||||
static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
|
||||
{
|
||||
while (--maxBytesToRead >= 0)
|
||||
{
|
||||
if (((signed char) *dataToTest) <= 0)
|
||||
return *dataToTest == 0;
|
||||
|
||||
++dataToTest;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
CharType* data;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,529 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_STRINGS_CHARPOINTER_UTF16_H_INCLUDED
|
||||
#define BEAST_STRINGS_CHARPOINTER_UTF16_H_INCLUDED
|
||||
|
||||
#include <beast/Config.h>
|
||||
#include <beast/strings/CharacterFunctions.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Wraps a pointer to a null-terminated UTF-16 character string, and provides
|
||||
various methods to operate on the data.
|
||||
@see CharPointer_UTF8, CharPointer_UTF32
|
||||
*/
|
||||
class CharPointer_UTF16
|
||||
{
|
||||
public:
|
||||
#if BEAST_NATIVE_WCHAR_IS_UTF16
|
||||
using CharType = wchar_t;
|
||||
#else
|
||||
using CharType = std::int16_t;
|
||||
#endif
|
||||
|
||||
inline explicit CharPointer_UTF16 (const CharType* const rawPointer) noexcept
|
||||
: data (const_cast <CharType*> (rawPointer))
|
||||
{
|
||||
}
|
||||
|
||||
inline CharPointer_UTF16 (const CharPointer_UTF16& other) noexcept
|
||||
: data (other.data)
|
||||
{
|
||||
}
|
||||
|
||||
inline CharPointer_UTF16 operator= (CharPointer_UTF16 other) noexcept
|
||||
{
|
||||
data = other.data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CharPointer_UTF16 operator= (const CharType* text) noexcept
|
||||
{
|
||||
data = const_cast <CharType*> (text);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** This is a pointer comparison, it doesn't compare the actual text. */
|
||||
inline bool operator== (CharPointer_UTF16 other) const noexcept { return data == other.data; }
|
||||
inline bool operator!= (CharPointer_UTF16 other) const noexcept { return data != other.data; }
|
||||
inline bool operator<= (CharPointer_UTF16 other) const noexcept { return data <= other.data; }
|
||||
inline bool operator< (CharPointer_UTF16 other) const noexcept { return data < other.data; }
|
||||
inline bool operator>= (CharPointer_UTF16 other) const noexcept { return data >= other.data; }
|
||||
inline bool operator> (CharPointer_UTF16 other) const noexcept { return data > other.data; }
|
||||
|
||||
/** Returns the address that this pointer is pointing to. */
|
||||
inline CharType* getAddress() const noexcept { return data; }
|
||||
|
||||
/** Returns the address that this pointer is pointing to. */
|
||||
inline operator const CharType*() const noexcept { return data; }
|
||||
|
||||
/** Returns true if this pointer is pointing to a null character. */
|
||||
inline bool isEmpty() const noexcept { return *data == 0; }
|
||||
|
||||
/** Returns the unicode character that this pointer is pointing to. */
|
||||
beast_wchar operator*() const noexcept
|
||||
{
|
||||
std::uint32_t n = (std::uint32_t) (std::uint16_t) *data;
|
||||
|
||||
if (n >= 0xd800 && n <= 0xdfff && ((std::uint32_t) (std::uint16_t) data[1]) >= 0xdc00)
|
||||
n = 0x10000 + (((n - 0xd800) << 10) | (((std::uint32_t) (std::uint16_t) data[1]) - 0xdc00));
|
||||
|
||||
return (beast_wchar) n;
|
||||
}
|
||||
|
||||
/** Moves this pointer along to the next character in the string. */
|
||||
CharPointer_UTF16 operator++() noexcept
|
||||
{
|
||||
const beast_wchar n = *data++;
|
||||
|
||||
if (n >= 0xd800 && n <= 0xdfff && ((std::uint32_t) (std::uint16_t) *data) >= 0xdc00)
|
||||
++data;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Moves this pointer back to the previous character in the string. */
|
||||
CharPointer_UTF16 operator--() noexcept
|
||||
{
|
||||
const beast_wchar n = *--data;
|
||||
|
||||
if (n >= 0xdc00 && n <= 0xdfff)
|
||||
--data;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Returns the character that this pointer is currently pointing to, and then
|
||||
advances the pointer to point to the next character. */
|
||||
beast_wchar getAndAdvance() noexcept
|
||||
{
|
||||
std::uint32_t n = (std::uint32_t) (std::uint16_t) *data++;
|
||||
|
||||
if (n >= 0xd800 && n <= 0xdfff && ((std::uint32_t) (std::uint16_t) *data) >= 0xdc00)
|
||||
n = 0x10000 + ((((n - 0xd800) << 10) | (((std::uint32_t) (std::uint16_t) *data++) - 0xdc00)));
|
||||
|
||||
return (beast_wchar) n;
|
||||
}
|
||||
|
||||
/** Moves this pointer along to the next character in the string. */
|
||||
CharPointer_UTF16 operator++ (int) noexcept
|
||||
{
|
||||
CharPointer_UTF16 temp (*this);
|
||||
++*this;
|
||||
return temp;
|
||||
}
|
||||
|
||||
/** Moves this pointer forwards by the specified number of characters. */
|
||||
void operator+= (int numToSkip) noexcept
|
||||
{
|
||||
if (numToSkip < 0)
|
||||
{
|
||||
while (++numToSkip <= 0)
|
||||
--*this;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (--numToSkip >= 0)
|
||||
++*this;
|
||||
}
|
||||
}
|
||||
|
||||
/** Moves this pointer backwards by the specified number of characters. */
|
||||
void operator-= (int numToSkip) noexcept
|
||||
{
|
||||
operator+= (-numToSkip);
|
||||
}
|
||||
|
||||
/** Returns the character at a given character index from the start of the string. */
|
||||
beast_wchar operator[] (const int characterIndex) const noexcept
|
||||
{
|
||||
CharPointer_UTF16 p (*this);
|
||||
p += characterIndex;
|
||||
return *p;
|
||||
}
|
||||
|
||||
/** Returns a pointer which is moved forwards from this one by the specified number of characters. */
|
||||
CharPointer_UTF16 operator+ (const int numToSkip) const noexcept
|
||||
{
|
||||
CharPointer_UTF16 p (*this);
|
||||
p += numToSkip;
|
||||
return p;
|
||||
}
|
||||
|
||||
/** Returns a pointer which is moved backwards from this one by the specified number of characters. */
|
||||
CharPointer_UTF16 operator- (const int numToSkip) const noexcept
|
||||
{
|
||||
CharPointer_UTF16 p (*this);
|
||||
p += -numToSkip;
|
||||
return p;
|
||||
}
|
||||
|
||||
/** Writes a unicode character to this string, and advances this pointer to point to the next position. */
|
||||
void write (beast_wchar charToWrite) noexcept
|
||||
{
|
||||
if (charToWrite >= 0x10000)
|
||||
{
|
||||
charToWrite -= 0x10000;
|
||||
*data++ = (CharType) (0xd800 + (charToWrite >> 10));
|
||||
*data++ = (CharType) (0xdc00 + (charToWrite & 0x3ff));
|
||||
}
|
||||
else
|
||||
{
|
||||
*data++ = (CharType) charToWrite;
|
||||
}
|
||||
}
|
||||
|
||||
/** Writes a null character to this string (leaving the pointer's position unchanged). */
|
||||
inline void writeNull() const noexcept
|
||||
{
|
||||
*data = 0;
|
||||
}
|
||||
|
||||
/** Returns the number of characters in this string. */
|
||||
size_t length() const noexcept
|
||||
{
|
||||
const CharType* d = data;
|
||||
size_t count = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const int n = *d++;
|
||||
|
||||
if (n >= 0xd800 && n <= 0xdfff)
|
||||
{
|
||||
if (*d++ == 0)
|
||||
break;
|
||||
}
|
||||
else if (n == 0)
|
||||
break;
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/** Returns the number of characters in this string, or the given value, whichever is lower. */
|
||||
size_t lengthUpTo (const size_t maxCharsToCount) const noexcept
|
||||
{
|
||||
return CharacterFunctions::lengthUpTo (*this, maxCharsToCount);
|
||||
}
|
||||
|
||||
/** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */
|
||||
size_t lengthUpTo (const CharPointer_UTF16 end) const noexcept
|
||||
{
|
||||
return CharacterFunctions::lengthUpTo (*this, end);
|
||||
}
|
||||
|
||||
/** Returns the number of bytes that are used to represent this string.
|
||||
This includes the terminating null character.
|
||||
*/
|
||||
size_t sizeInBytes() const noexcept
|
||||
{
|
||||
return sizeof (CharType) * (findNullIndex (data) + 1);
|
||||
}
|
||||
|
||||
/** Returns the number of bytes that would be needed to represent the given
|
||||
unicode character in this encoding format.
|
||||
*/
|
||||
static size_t getBytesRequiredFor (const beast_wchar charToWrite) noexcept
|
||||
{
|
||||
return (charToWrite >= 0x10000) ? (sizeof (CharType) * 2) : sizeof (CharType);
|
||||
}
|
||||
|
||||
/** Returns the number of bytes that would be needed to represent the given
|
||||
string in this encoding format.
|
||||
The value returned does NOT include the terminating null character.
|
||||
*/
|
||||
template <class CharPointer>
|
||||
static size_t getBytesRequiredFor (CharPointer text) noexcept
|
||||
{
|
||||
size_t count = 0;
|
||||
beast_wchar n;
|
||||
|
||||
while ((n = text.getAndAdvance()) != 0)
|
||||
count += getBytesRequiredFor (n);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/** Returns a pointer to the null character that terminates this string. */
|
||||
CharPointer_UTF16 findTerminatingNull() const noexcept
|
||||
{
|
||||
const CharType* t = data;
|
||||
|
||||
while (*t != 0)
|
||||
++t;
|
||||
|
||||
return CharPointer_UTF16 (t);
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes. */
|
||||
template <typename CharPointer>
|
||||
void writeAll (const CharPointer src) noexcept
|
||||
{
|
||||
CharacterFunctions::copyAll (*this, src);
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes. */
|
||||
void writeAll (const CharPointer_UTF16 src) noexcept
|
||||
{
|
||||
const CharType* s = src.data;
|
||||
|
||||
while ((*data = *s) != 0)
|
||||
{
|
||||
++data;
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes.
|
||||
The maxDestBytes parameter specifies the maximum number of bytes that can be written
|
||||
to the destination buffer before stopping.
|
||||
*/
|
||||
template <typename CharPointer>
|
||||
size_t writeWithDestByteLimit (const CharPointer src, const size_t maxDestBytes) noexcept
|
||||
{
|
||||
return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes);
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes.
|
||||
The maxChars parameter specifies the maximum number of characters that can be
|
||||
written to the destination buffer before stopping (including the terminating null).
|
||||
*/
|
||||
template <typename CharPointer>
|
||||
void writeWithCharLimit (const CharPointer src, const int maxChars) noexcept
|
||||
{
|
||||
CharacterFunctions::copyWithCharLimit (*this, src, maxChars);
|
||||
}
|
||||
|
||||
/** Compares this string with another one. */
|
||||
template <typename CharPointer>
|
||||
int compare (const CharPointer other) const noexcept
|
||||
{
|
||||
return CharacterFunctions::compare (*this, other);
|
||||
}
|
||||
|
||||
/** Compares this string with another one, up to a specified number of characters. */
|
||||
template <typename CharPointer>
|
||||
int compareUpTo (const CharPointer other, const int maxChars) const noexcept
|
||||
{
|
||||
return CharacterFunctions::compareUpTo (*this, other, maxChars);
|
||||
}
|
||||
|
||||
/** Compares this string with another one. */
|
||||
template <typename CharPointer>
|
||||
int compareIgnoreCase (const CharPointer other) const noexcept
|
||||
{
|
||||
return CharacterFunctions::compareIgnoreCase (*this, other);
|
||||
}
|
||||
|
||||
/** Compares this string with another one, up to a specified number of characters. */
|
||||
template <typename CharPointer>
|
||||
int compareIgnoreCaseUpTo (const CharPointer other, const int maxChars) const noexcept
|
||||
{
|
||||
return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars);
|
||||
}
|
||||
|
||||
#if BEAST_WINDOWS && ! DOXYGEN
|
||||
int compareIgnoreCase (const CharPointer_UTF16 other) const noexcept
|
||||
{
|
||||
return _wcsicmp (data, other.data);
|
||||
}
|
||||
|
||||
int compareIgnoreCaseUpTo (const CharPointer_UTF16 other, int maxChars) const noexcept
|
||||
{
|
||||
return _wcsnicmp (data, other.data, (size_t) maxChars);
|
||||
}
|
||||
|
||||
int indexOf (const CharPointer_UTF16 stringToFind) const noexcept
|
||||
{
|
||||
const CharType* const t = wcsstr (data, stringToFind.getAddress());
|
||||
return t == nullptr ? -1 : (int) (t - data);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Returns the character index of a substring, or -1 if it isn't found. */
|
||||
template <typename CharPointer>
|
||||
int indexOf (const CharPointer stringToFind) const noexcept
|
||||
{
|
||||
return CharacterFunctions::indexOf (*this, stringToFind);
|
||||
}
|
||||
|
||||
/** Returns the character index of a unicode character, or -1 if it isn't found. */
|
||||
int indexOf (const beast_wchar charToFind) const noexcept
|
||||
{
|
||||
return CharacterFunctions::indexOfChar (*this, charToFind);
|
||||
}
|
||||
|
||||
/** Returns the character index of a unicode character, or -1 if it isn't found. */
|
||||
int indexOf (const beast_wchar charToFind, const bool ignoreCase) const noexcept
|
||||
{
|
||||
return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind)
|
||||
: CharacterFunctions::indexOfChar (*this, charToFind);
|
||||
}
|
||||
|
||||
/** Returns true if the first character of this string is whitespace. */
|
||||
bool isWhitespace() const noexcept { return CharacterFunctions::isWhitespace (operator*()) != 0; }
|
||||
/** Returns true if the first character of this string is a digit. */
|
||||
bool isDigit() const noexcept { return CharacterFunctions::isDigit (operator*()) != 0; }
|
||||
/** Returns true if the first character of this string is a letter. */
|
||||
bool isLetter() const noexcept { return CharacterFunctions::isLetter (operator*()) != 0; }
|
||||
/** Returns true if the first character of this string is a letter or digit. */
|
||||
bool isLetterOrDigit() const noexcept { return CharacterFunctions::isLetterOrDigit (operator*()) != 0; }
|
||||
/** Returns true if the first character of this string is upper-case. */
|
||||
bool isUpperCase() const noexcept { return CharacterFunctions::isUpperCase (operator*()) != 0; }
|
||||
/** Returns true if the first character of this string is lower-case. */
|
||||
bool isLowerCase() const noexcept { return CharacterFunctions::isLowerCase (operator*()) != 0; }
|
||||
|
||||
/** Returns an upper-case version of the first character of this string. */
|
||||
beast_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase (operator*()); }
|
||||
/** Returns a lower-case version of the first character of this string. */
|
||||
beast_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase (operator*()); }
|
||||
|
||||
/** Parses this string as a 32-bit integer. */
|
||||
int getIntValue32() const noexcept
|
||||
{
|
||||
#if BEAST_WINDOWS
|
||||
return _wtoi (data);
|
||||
#else
|
||||
return CharacterFunctions::getIntValue <int, CharPointer_UTF16> (*this);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Parses this string as a 64-bit integer. */
|
||||
std::int64_t getIntValue64() const noexcept
|
||||
{
|
||||
#if BEAST_WINDOWS
|
||||
return _wtoi64 (data);
|
||||
#else
|
||||
return CharacterFunctions::getIntValue <std::int64_t, CharPointer_UTF16> (*this);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Parses this string as a floating point double. */
|
||||
double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); }
|
||||
|
||||
/** Returns the first non-whitespace character in the string. */
|
||||
CharPointer_UTF16 findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); }
|
||||
|
||||
/** Returns true if the given unicode character can be represented in this encoding. */
|
||||
static bool canRepresent (beast_wchar character) noexcept
|
||||
{
|
||||
return ((unsigned int) character) < (unsigned int) 0x10ffff
|
||||
&& (((unsigned int) character) < 0xd800 || ((unsigned int) character) > 0xdfff);
|
||||
}
|
||||
|
||||
/** Returns true if this data contains a valid string in this encoding. */
|
||||
static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
|
||||
{
|
||||
maxBytesToRead /= sizeof (CharType);
|
||||
|
||||
while (--maxBytesToRead >= 0 && *dataToTest != 0)
|
||||
{
|
||||
const std::uint32_t n = (std::uint32_t) (std::uint16_t) *dataToTest++;
|
||||
|
||||
if (n >= 0xd800)
|
||||
{
|
||||
if (n > 0x10ffff)
|
||||
return false;
|
||||
|
||||
if (n <= 0xdfff)
|
||||
{
|
||||
if (n > 0xdc00)
|
||||
return false;
|
||||
|
||||
const std::uint32_t nextChar = (std::uint32_t) (std::uint16_t) *dataToTest++;
|
||||
|
||||
if (nextChar < 0xdc00 || nextChar > 0xdfff)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Atomically swaps this pointer for a new value, returning the previous value. */
|
||||
CharPointer_UTF16 atomicSwap (const CharPointer_UTF16 newValue)
|
||||
{
|
||||
return CharPointer_UTF16 (reinterpret_cast <std::atomic<CharType*>&> (data).exchange (newValue.data));
|
||||
}
|
||||
|
||||
/** These values are the byte-order-mark (BOM) values for a UTF-16 stream. */
|
||||
enum
|
||||
{
|
||||
byteOrderMarkBE1 = 0xfe,
|
||||
byteOrderMarkBE2 = 0xff,
|
||||
byteOrderMarkLE1 = 0xff,
|
||||
byteOrderMarkLE2 = 0xfe
|
||||
};
|
||||
|
||||
/** Returns true if the first pair of bytes in this pointer are the UTF16 byte-order mark (big endian).
|
||||
The pointer must not be null, and must contain at least two valid bytes.
|
||||
*/
|
||||
static bool isByteOrderMarkBigEndian (const void* possibleByteOrder) noexcept
|
||||
{
|
||||
bassert (possibleByteOrder != nullptr);
|
||||
const std::uint8_t* const c = static_cast<const std::uint8_t*> (possibleByteOrder);
|
||||
|
||||
return c[0] == (std::uint8_t) byteOrderMarkBE1
|
||||
&& c[1] == (std::uint8_t) byteOrderMarkBE2;
|
||||
}
|
||||
|
||||
/** Returns true if the first pair of bytes in this pointer are the UTF16 byte-order mark (little endian).
|
||||
The pointer must not be null, and must contain at least two valid bytes.
|
||||
*/
|
||||
static bool isByteOrderMarkLittleEndian (const void* possibleByteOrder) noexcept
|
||||
{
|
||||
bassert (possibleByteOrder != nullptr);
|
||||
const std::uint8_t* const c = static_cast<const std::uint8_t*> (possibleByteOrder);
|
||||
|
||||
return c[0] == (std::uint8_t) byteOrderMarkLE1
|
||||
&& c[1] == (std::uint8_t) byteOrderMarkLE2;
|
||||
}
|
||||
|
||||
private:
|
||||
CharType* data;
|
||||
|
||||
static unsigned int findNullIndex (const CharType* const t) noexcept
|
||||
{
|
||||
unsigned int n = 0;
|
||||
|
||||
while (t[n] != 0)
|
||||
++n;
|
||||
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,382 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_STRINGS_CHARPOINTER_UTF32_H_INCLUDED
|
||||
#define BEAST_STRINGS_CHARPOINTER_UTF32_H_INCLUDED
|
||||
|
||||
#include <beast/Config.h>
|
||||
#include <beast/strings/CharacterFunctions.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cwchar>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Wraps a pointer to a null-terminated UTF-32 character string, and provides
|
||||
various methods to operate on the data.
|
||||
@see CharPointer_UTF8, CharPointer_UTF16
|
||||
*/
|
||||
class CharPointer_UTF32
|
||||
{
|
||||
public:
|
||||
using CharType = beast_wchar;
|
||||
|
||||
inline explicit CharPointer_UTF32 (const CharType* const rawPointer) noexcept
|
||||
: data (const_cast <CharType*> (rawPointer))
|
||||
{
|
||||
}
|
||||
|
||||
inline CharPointer_UTF32 (const CharPointer_UTF32& other) noexcept
|
||||
: data (other.data)
|
||||
{
|
||||
}
|
||||
|
||||
inline CharPointer_UTF32 operator= (CharPointer_UTF32 other) noexcept
|
||||
{
|
||||
data = other.data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CharPointer_UTF32 operator= (const CharType* text) noexcept
|
||||
{
|
||||
data = const_cast <CharType*> (text);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** This is a pointer comparison, it doesn't compare the actual text. */
|
||||
inline bool operator== (CharPointer_UTF32 other) const noexcept { return data == other.data; }
|
||||
inline bool operator!= (CharPointer_UTF32 other) const noexcept { return data != other.data; }
|
||||
inline bool operator<= (CharPointer_UTF32 other) const noexcept { return data <= other.data; }
|
||||
inline bool operator< (CharPointer_UTF32 other) const noexcept { return data < other.data; }
|
||||
inline bool operator>= (CharPointer_UTF32 other) const noexcept { return data >= other.data; }
|
||||
inline bool operator> (CharPointer_UTF32 other) const noexcept { return data > other.data; }
|
||||
|
||||
/** Returns the address that this pointer is pointing to. */
|
||||
inline CharType* getAddress() const noexcept { return data; }
|
||||
|
||||
/** Returns the address that this pointer is pointing to. */
|
||||
inline operator const CharType*() const noexcept { return data; }
|
||||
|
||||
/** Returns true if this pointer is pointing to a null character. */
|
||||
inline bool isEmpty() const noexcept { return *data == 0; }
|
||||
|
||||
/** Returns the unicode character that this pointer is pointing to. */
|
||||
inline beast_wchar operator*() const noexcept { return *data; }
|
||||
|
||||
/** Moves this pointer along to the next character in the string. */
|
||||
inline CharPointer_UTF32 operator++() noexcept
|
||||
{
|
||||
++data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Moves this pointer to the previous character in the string. */
|
||||
inline CharPointer_UTF32 operator--() noexcept
|
||||
{
|
||||
--data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Returns the character that this pointer is currently pointing to, and then
|
||||
advances the pointer to point to the next character. */
|
||||
inline beast_wchar getAndAdvance() noexcept { return *data++; }
|
||||
|
||||
/** Moves this pointer along to the next character in the string. */
|
||||
CharPointer_UTF32 operator++ (int) noexcept
|
||||
{
|
||||
CharPointer_UTF32 temp (*this);
|
||||
++data;
|
||||
return temp;
|
||||
}
|
||||
|
||||
/** Moves this pointer forwards by the specified number of characters. */
|
||||
inline void operator+= (const int numToSkip) noexcept
|
||||
{
|
||||
data += numToSkip;
|
||||
}
|
||||
|
||||
inline void operator-= (const int numToSkip) noexcept
|
||||
{
|
||||
data -= numToSkip;
|
||||
}
|
||||
|
||||
/** Returns the character at a given character index from the start of the string. */
|
||||
inline beast_wchar& operator[] (const int characterIndex) const noexcept
|
||||
{
|
||||
return data [characterIndex];
|
||||
}
|
||||
|
||||
/** Returns a pointer which is moved forwards from this one by the specified number of characters. */
|
||||
CharPointer_UTF32 operator+ (const int numToSkip) const noexcept
|
||||
{
|
||||
return CharPointer_UTF32 (data + numToSkip);
|
||||
}
|
||||
|
||||
/** Returns a pointer which is moved backwards from this one by the specified number of characters. */
|
||||
CharPointer_UTF32 operator- (const int numToSkip) const noexcept
|
||||
{
|
||||
return CharPointer_UTF32 (data - numToSkip);
|
||||
}
|
||||
|
||||
/** Writes a unicode character to this string, and advances this pointer to point to the next position. */
|
||||
inline void write (const beast_wchar charToWrite) noexcept
|
||||
{
|
||||
*data++ = charToWrite;
|
||||
}
|
||||
|
||||
inline void replaceChar (const beast_wchar newChar) noexcept
|
||||
{
|
||||
*data = newChar;
|
||||
}
|
||||
|
||||
/** Writes a null character to this string (leaving the pointer's position unchanged). */
|
||||
inline void writeNull() const noexcept
|
||||
{
|
||||
*data = 0;
|
||||
}
|
||||
|
||||
/** Returns the number of characters in this string. */
|
||||
size_t length() const noexcept
|
||||
{
|
||||
#if BEAST_NATIVE_WCHAR_IS_UTF32 && ! BEAST_ANDROID
|
||||
return wcslen (data);
|
||||
#else
|
||||
size_t n = 0;
|
||||
while (data[n] != 0)
|
||||
++n;
|
||||
return n;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Returns the number of characters in this string, or the given value, whichever is lower. */
|
||||
size_t lengthUpTo (const size_t maxCharsToCount) const noexcept
|
||||
{
|
||||
return CharacterFunctions::lengthUpTo (*this, maxCharsToCount);
|
||||
}
|
||||
|
||||
/** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */
|
||||
size_t lengthUpTo (const CharPointer_UTF32 end) const noexcept
|
||||
{
|
||||
return CharacterFunctions::lengthUpTo (*this, end);
|
||||
}
|
||||
|
||||
/** Returns the number of bytes that are used to represent this string.
|
||||
This includes the terminating null character.
|
||||
*/
|
||||
size_t sizeInBytes() const noexcept
|
||||
{
|
||||
return sizeof (CharType) * (length() + 1);
|
||||
}
|
||||
|
||||
/** Returns the number of bytes that would be needed to represent the given
|
||||
unicode character in this encoding format.
|
||||
*/
|
||||
static inline size_t getBytesRequiredFor (const beast_wchar) noexcept
|
||||
{
|
||||
return sizeof (CharType);
|
||||
}
|
||||
|
||||
/** Returns the number of bytes that would be needed to represent the given
|
||||
string in this encoding format.
|
||||
The value returned does NOT include the terminating null character.
|
||||
*/
|
||||
template <class CharPointer>
|
||||
static size_t getBytesRequiredFor (const CharPointer text) noexcept
|
||||
{
|
||||
return sizeof (CharType) * text.length();
|
||||
}
|
||||
|
||||
/** Returns a pointer to the null character that terminates this string. */
|
||||
CharPointer_UTF32 findTerminatingNull() const noexcept
|
||||
{
|
||||
return CharPointer_UTF32 (data + length());
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes. */
|
||||
template <typename CharPointer>
|
||||
void writeAll (const CharPointer src) noexcept
|
||||
{
|
||||
CharacterFunctions::copyAll (*this, src);
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes. */
|
||||
void writeAll (const CharPointer_UTF32 src) noexcept
|
||||
{
|
||||
const CharType* s = src.data;
|
||||
|
||||
while ((*data = *s) != 0)
|
||||
{
|
||||
++data;
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes.
|
||||
The maxDestBytes parameter specifies the maximum number of bytes that can be written
|
||||
to the destination buffer before stopping.
|
||||
*/
|
||||
template <typename CharPointer>
|
||||
size_t writeWithDestByteLimit (const CharPointer src, const size_t maxDestBytes) noexcept
|
||||
{
|
||||
return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes);
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes.
|
||||
The maxChars parameter specifies the maximum number of characters that can be
|
||||
written to the destination buffer before stopping (including the terminating null).
|
||||
*/
|
||||
template <typename CharPointer>
|
||||
void writeWithCharLimit (const CharPointer src, const int maxChars) noexcept
|
||||
{
|
||||
CharacterFunctions::copyWithCharLimit (*this, src, maxChars);
|
||||
}
|
||||
|
||||
/** Compares this string with another one. */
|
||||
template <typename CharPointer>
|
||||
int compare (const CharPointer other) const noexcept
|
||||
{
|
||||
return CharacterFunctions::compare (*this, other);
|
||||
}
|
||||
|
||||
#if BEAST_NATIVE_WCHAR_IS_UTF32 && ! BEAST_ANDROID
|
||||
/** Compares this string with another one. */
|
||||
int compare (const CharPointer_UTF32 other) const noexcept
|
||||
{
|
||||
return wcscmp (data, other.data);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Compares this string with another one, up to a specified number of characters. */
|
||||
template <typename CharPointer>
|
||||
int compareUpTo (const CharPointer other, const int maxChars) const noexcept
|
||||
{
|
||||
return CharacterFunctions::compareUpTo (*this, other, maxChars);
|
||||
}
|
||||
|
||||
/** Compares this string with another one. */
|
||||
template <typename CharPointer>
|
||||
int compareIgnoreCase (const CharPointer other) const
|
||||
{
|
||||
return CharacterFunctions::compareIgnoreCase (*this, other);
|
||||
}
|
||||
|
||||
/** Compares this string with another one, up to a specified number of characters. */
|
||||
template <typename CharPointer>
|
||||
int compareIgnoreCaseUpTo (const CharPointer other, const int maxChars) const noexcept
|
||||
{
|
||||
return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars);
|
||||
}
|
||||
|
||||
/** Returns the character index of a substring, or -1 if it isn't found. */
|
||||
template <typename CharPointer>
|
||||
int indexOf (const CharPointer stringToFind) const noexcept
|
||||
{
|
||||
return CharacterFunctions::indexOf (*this, stringToFind);
|
||||
}
|
||||
|
||||
/** Returns the character index of a unicode character, or -1 if it isn't found. */
|
||||
int indexOf (const beast_wchar charToFind) const noexcept
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (data[i] != 0)
|
||||
{
|
||||
if (data[i] == charToFind)
|
||||
return i;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Returns the character index of a unicode character, or -1 if it isn't found. */
|
||||
int indexOf (const beast_wchar charToFind, const bool ignoreCase) const noexcept
|
||||
{
|
||||
return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind)
|
||||
: CharacterFunctions::indexOfChar (*this, charToFind);
|
||||
}
|
||||
|
||||
/** Returns true if the first character of this string is whitespace. */
|
||||
bool isWhitespace() const { return CharacterFunctions::isWhitespace (*data) != 0; }
|
||||
/** Returns true if the first character of this string is a digit. */
|
||||
bool isDigit() const { return CharacterFunctions::isDigit (*data) != 0; }
|
||||
/** Returns true if the first character of this string is a letter. */
|
||||
bool isLetter() const { return CharacterFunctions::isLetter (*data) != 0; }
|
||||
/** Returns true if the first character of this string is a letter or digit. */
|
||||
bool isLetterOrDigit() const { return CharacterFunctions::isLetterOrDigit (*data) != 0; }
|
||||
/** Returns true if the first character of this string is upper-case. */
|
||||
bool isUpperCase() const { return CharacterFunctions::isUpperCase (*data) != 0; }
|
||||
/** Returns true if the first character of this string is lower-case. */
|
||||
bool isLowerCase() const { return CharacterFunctions::isLowerCase (*data) != 0; }
|
||||
|
||||
/** Returns an upper-case version of the first character of this string. */
|
||||
beast_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase (*data); }
|
||||
/** Returns a lower-case version of the first character of this string. */
|
||||
beast_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase (*data); }
|
||||
|
||||
/** Parses this string as a 32-bit integer. */
|
||||
int getIntValue32() const noexcept { return CharacterFunctions::getIntValue <int, CharPointer_UTF32> (*this); }
|
||||
/** Parses this string as a 64-bit integer. */
|
||||
std::int64_t getIntValue64() const noexcept { return CharacterFunctions::getIntValue <std::int64_t, CharPointer_UTF32> (*this); }
|
||||
|
||||
/** Parses this string as a floating point double. */
|
||||
double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); }
|
||||
|
||||
/** Returns the first non-whitespace character in the string. */
|
||||
CharPointer_UTF32 findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); }
|
||||
|
||||
/** Returns true if the given unicode character can be represented in this encoding. */
|
||||
static bool canRepresent (beast_wchar character) noexcept
|
||||
{
|
||||
return ((unsigned int) character) < (unsigned int) 0x10ffff;
|
||||
}
|
||||
|
||||
/** Returns true if this data contains a valid string in this encoding. */
|
||||
static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
|
||||
{
|
||||
maxBytesToRead /= sizeof (CharType);
|
||||
|
||||
while (--maxBytesToRead >= 0 && *dataToTest != 0)
|
||||
if (! canRepresent (*dataToTest++))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Atomically swaps this pointer for a new value, returning the previous value. */
|
||||
CharPointer_UTF32 atomicSwap (const CharPointer_UTF32 newValue)
|
||||
{
|
||||
return CharPointer_UTF32 (reinterpret_cast <std::atomic<CharType*>&> (data).exchange (newValue.data));
|
||||
}
|
||||
|
||||
private:
|
||||
CharType* data;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,585 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_STRINGS_CHARPOINTER_UTF8_H_INCLUDED
|
||||
#define BEAST_STRINGS_CHARPOINTER_UTF8_H_INCLUDED
|
||||
|
||||
#include <beast/Config.h>
|
||||
#include <beast/strings/CharacterFunctions.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Wraps a pointer to a null-terminated UTF-8 character string, and provides
|
||||
various methods to operate on the data.
|
||||
@see CharPointer_UTF16, CharPointer_UTF32
|
||||
*/
|
||||
class CharPointer_UTF8
|
||||
{
|
||||
public:
|
||||
using CharType = char;
|
||||
|
||||
inline explicit CharPointer_UTF8 (const CharType* const rawPointer) noexcept
|
||||
: data (const_cast <CharType*> (rawPointer))
|
||||
{
|
||||
}
|
||||
|
||||
inline CharPointer_UTF8 (const CharPointer_UTF8& other) noexcept
|
||||
: data (other.data)
|
||||
{
|
||||
}
|
||||
|
||||
inline CharPointer_UTF8 operator= (CharPointer_UTF8 other) noexcept
|
||||
{
|
||||
data = other.data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CharPointer_UTF8 operator= (const CharType* text) noexcept
|
||||
{
|
||||
data = const_cast <CharType*> (text);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** This is a pointer comparison, it doesn't compare the actual text. */
|
||||
inline bool operator== (CharPointer_UTF8 other) const noexcept { return data == other.data; }
|
||||
inline bool operator!= (CharPointer_UTF8 other) const noexcept { return data != other.data; }
|
||||
inline bool operator<= (CharPointer_UTF8 other) const noexcept { return data <= other.data; }
|
||||
inline bool operator< (CharPointer_UTF8 other) const noexcept { return data < other.data; }
|
||||
inline bool operator>= (CharPointer_UTF8 other) const noexcept { return data >= other.data; }
|
||||
inline bool operator> (CharPointer_UTF8 other) const noexcept { return data > other.data; }
|
||||
|
||||
/** Returns the address that this pointer is pointing to. */
|
||||
inline CharType* getAddress() const noexcept { return data; }
|
||||
|
||||
/** Returns the address that this pointer is pointing to. */
|
||||
inline operator const CharType*() const noexcept { return data; }
|
||||
|
||||
/** Returns true if this pointer is pointing to a null character. */
|
||||
inline bool isEmpty() const noexcept { return *data == 0; }
|
||||
|
||||
/** Returns the unicode character that this pointer is pointing to. */
|
||||
beast_wchar operator*() const noexcept
|
||||
{
|
||||
const signed char byte = (signed char) *data;
|
||||
|
||||
if (byte >= 0)
|
||||
return (beast_wchar) (std::uint8_t) byte;
|
||||
|
||||
std::uint32_t n = (std::uint32_t) (std::uint8_t) byte;
|
||||
std::uint32_t mask = 0x7f;
|
||||
std::uint32_t bit = 0x40;
|
||||
size_t numExtraValues = 0;
|
||||
|
||||
while ((n & bit) != 0 && bit > 0x10)
|
||||
{
|
||||
mask >>= 1;
|
||||
++numExtraValues;
|
||||
bit >>= 1;
|
||||
}
|
||||
|
||||
n &= mask;
|
||||
|
||||
for (size_t i = 1; i <= numExtraValues; ++i)
|
||||
{
|
||||
const std::uint8_t nextByte = (std::uint8_t) data [i];
|
||||
|
||||
if ((nextByte & 0xc0) != 0x80)
|
||||
break;
|
||||
|
||||
n <<= 6;
|
||||
n |= (nextByte & 0x3f);
|
||||
}
|
||||
|
||||
return (beast_wchar) n;
|
||||
}
|
||||
|
||||
/** Moves this pointer along to the next character in the string. */
|
||||
CharPointer_UTF8& operator++() noexcept
|
||||
{
|
||||
const signed char n = (signed char) *data++;
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
beast_wchar bit = 0x40;
|
||||
|
||||
while ((n & bit) != 0 && bit > 0x8)
|
||||
{
|
||||
++data;
|
||||
bit >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Moves this pointer back to the previous character in the string. */
|
||||
CharPointer_UTF8 operator--() noexcept
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
while ((*--data & 0xc0) == 0x80 && ++count < 4)
|
||||
{}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Returns the character that this pointer is currently pointing to, and then
|
||||
advances the pointer to point to the next character. */
|
||||
beast_wchar getAndAdvance() noexcept
|
||||
{
|
||||
const signed char byte = (signed char) *data++;
|
||||
|
||||
if (byte >= 0)
|
||||
return (beast_wchar) (std::uint8_t) byte;
|
||||
|
||||
std::uint32_t n = (std::uint32_t) (std::uint8_t) byte;
|
||||
std::uint32_t mask = 0x7f;
|
||||
std::uint32_t bit = 0x40;
|
||||
int numExtraValues = 0;
|
||||
|
||||
while ((n & bit) != 0 && bit > 0x8)
|
||||
{
|
||||
mask >>= 1;
|
||||
++numExtraValues;
|
||||
bit >>= 1;
|
||||
}
|
||||
|
||||
n &= mask;
|
||||
|
||||
while (--numExtraValues >= 0)
|
||||
{
|
||||
const std::uint32_t nextByte = (std::uint32_t) (std::uint8_t) *data++;
|
||||
|
||||
if ((nextByte & 0xc0) != 0x80)
|
||||
break;
|
||||
|
||||
n <<= 6;
|
||||
n |= (nextByte & 0x3f);
|
||||
}
|
||||
|
||||
return (beast_wchar) n;
|
||||
}
|
||||
|
||||
/** Moves this pointer along to the next character in the string. */
|
||||
CharPointer_UTF8 operator++ (int) noexcept
|
||||
{
|
||||
CharPointer_UTF8 temp (*this);
|
||||
++*this;
|
||||
return temp;
|
||||
}
|
||||
|
||||
/** Moves this pointer forwards by the specified number of characters. */
|
||||
void operator+= (int numToSkip) noexcept
|
||||
{
|
||||
if (numToSkip < 0)
|
||||
{
|
||||
while (++numToSkip <= 0)
|
||||
--*this;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (--numToSkip >= 0)
|
||||
++*this;
|
||||
}
|
||||
}
|
||||
|
||||
/** Moves this pointer backwards by the specified number of characters. */
|
||||
void operator-= (int numToSkip) noexcept
|
||||
{
|
||||
operator+= (-numToSkip);
|
||||
}
|
||||
|
||||
/** Returns the character at a given character index from the start of the string. */
|
||||
beast_wchar operator[] (int characterIndex) const noexcept
|
||||
{
|
||||
CharPointer_UTF8 p (*this);
|
||||
p += characterIndex;
|
||||
return *p;
|
||||
}
|
||||
|
||||
/** Returns a pointer which is moved forwards from this one by the specified number of characters. */
|
||||
CharPointer_UTF8 operator+ (int numToSkip) const noexcept
|
||||
{
|
||||
CharPointer_UTF8 p (*this);
|
||||
p += numToSkip;
|
||||
return p;
|
||||
}
|
||||
|
||||
/** Returns a pointer which is moved backwards from this one by the specified number of characters. */
|
||||
CharPointer_UTF8 operator- (int numToSkip) const noexcept
|
||||
{
|
||||
CharPointer_UTF8 p (*this);
|
||||
p += -numToSkip;
|
||||
return p;
|
||||
}
|
||||
|
||||
/** Returns the number of characters in this string. */
|
||||
size_t length() const noexcept
|
||||
{
|
||||
const CharType* d = data;
|
||||
size_t count = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const std::uint32_t n = (std::uint32_t) (std::uint8_t) *d++;
|
||||
|
||||
if ((n & 0x80) != 0)
|
||||
{
|
||||
std::uint32_t bit = 0x40;
|
||||
|
||||
while ((n & bit) != 0)
|
||||
{
|
||||
++d;
|
||||
bit >>= 1;
|
||||
|
||||
if (bit == 0)
|
||||
break; // illegal utf-8 sequence
|
||||
}
|
||||
}
|
||||
else if (n == 0)
|
||||
break;
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/** Returns the number of characters in this string, or the given value, whichever is lower. */
|
||||
size_t lengthUpTo (const size_t maxCharsToCount) const noexcept
|
||||
{
|
||||
return CharacterFunctions::lengthUpTo (*this, maxCharsToCount);
|
||||
}
|
||||
|
||||
/** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */
|
||||
size_t lengthUpTo (const CharPointer_UTF8 end) const noexcept
|
||||
{
|
||||
return CharacterFunctions::lengthUpTo (*this, end);
|
||||
}
|
||||
|
||||
/** Returns the number of bytes that are used to represent this string.
|
||||
This includes the terminating null character.
|
||||
*/
|
||||
size_t sizeInBytes() const noexcept
|
||||
{
|
||||
bassert (data != nullptr);
|
||||
return strlen (data) + 1;
|
||||
}
|
||||
|
||||
/** Returns the number of bytes that would be needed to represent the given
|
||||
unicode character in this encoding format.
|
||||
*/
|
||||
static size_t getBytesRequiredFor (const beast_wchar charToWrite) noexcept
|
||||
{
|
||||
size_t num = 1;
|
||||
const std::uint32_t c = (std::uint32_t) charToWrite;
|
||||
|
||||
if (c >= 0x80)
|
||||
{
|
||||
++num;
|
||||
if (c >= 0x800)
|
||||
{
|
||||
++num;
|
||||
if (c >= 0x10000)
|
||||
++num;
|
||||
}
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
/** Returns the number of bytes that would be needed to represent the given
|
||||
string in this encoding format.
|
||||
The value returned does NOT include the terminating null character.
|
||||
*/
|
||||
template <class CharPointer>
|
||||
static size_t getBytesRequiredFor (CharPointer text) noexcept
|
||||
{
|
||||
size_t count = 0;
|
||||
beast_wchar n;
|
||||
|
||||
while ((n = text.getAndAdvance()) != 0)
|
||||
count += getBytesRequiredFor (n);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/** Returns a pointer to the null character that terminates this string. */
|
||||
CharPointer_UTF8 findTerminatingNull() const noexcept
|
||||
{
|
||||
return CharPointer_UTF8 (data + strlen (data));
|
||||
}
|
||||
|
||||
/** Writes a unicode character to this string, and advances this pointer to point to the next position. */
|
||||
void write (const beast_wchar charToWrite) noexcept
|
||||
{
|
||||
const std::uint32_t c = (std::uint32_t) charToWrite;
|
||||
|
||||
if (c >= 0x80)
|
||||
{
|
||||
int numExtraBytes = 1;
|
||||
if (c >= 0x800)
|
||||
{
|
||||
++numExtraBytes;
|
||||
if (c >= 0x10000)
|
||||
++numExtraBytes;
|
||||
}
|
||||
|
||||
*data++ = (CharType) ((std::uint32_t) (0xff << (7 - numExtraBytes)) | (c >> (numExtraBytes * 6)));
|
||||
|
||||
while (--numExtraBytes >= 0)
|
||||
*data++ = (CharType) (0x80 | (0x3f & (c >> (numExtraBytes * 6))));
|
||||
}
|
||||
else
|
||||
{
|
||||
*data++ = (CharType) c;
|
||||
}
|
||||
}
|
||||
|
||||
/** Writes a null character to this string (leaving the pointer's position unchanged). */
|
||||
inline void writeNull() const noexcept
|
||||
{
|
||||
*data = 0;
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes. */
|
||||
template <typename CharPointer>
|
||||
void writeAll (const CharPointer src) noexcept
|
||||
{
|
||||
CharacterFunctions::copyAll (*this, src);
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes. */
|
||||
void writeAll (const CharPointer_UTF8 src) noexcept
|
||||
{
|
||||
const CharType* s = src.data;
|
||||
|
||||
while ((*data = *s) != 0)
|
||||
{
|
||||
++data;
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes.
|
||||
The maxDestBytes parameter specifies the maximum number of bytes that can be written
|
||||
to the destination buffer before stopping.
|
||||
*/
|
||||
template <typename CharPointer>
|
||||
size_t writeWithDestByteLimit (const CharPointer src, const size_t maxDestBytes) noexcept
|
||||
{
|
||||
return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes);
|
||||
}
|
||||
|
||||
/** Copies a source string to this pointer, advancing this pointer as it goes.
|
||||
The maxChars parameter specifies the maximum number of characters that can be
|
||||
written to the destination buffer before stopping (including the terminating null).
|
||||
*/
|
||||
template <typename CharPointer>
|
||||
void writeWithCharLimit (const CharPointer src, const int maxChars) noexcept
|
||||
{
|
||||
CharacterFunctions::copyWithCharLimit (*this, src, maxChars);
|
||||
}
|
||||
|
||||
/** Compares this string with another one. */
|
||||
template <typename CharPointer>
|
||||
int compare (const CharPointer other) const noexcept
|
||||
{
|
||||
return CharacterFunctions::compare (*this, other);
|
||||
}
|
||||
|
||||
/** Compares this string with another one, up to a specified number of characters. */
|
||||
template <typename CharPointer>
|
||||
int compareUpTo (const CharPointer other, const int maxChars) const noexcept
|
||||
{
|
||||
return CharacterFunctions::compareUpTo (*this, other, maxChars);
|
||||
}
|
||||
|
||||
/** Compares this string with another one. */
|
||||
template <typename CharPointer>
|
||||
int compareIgnoreCase (const CharPointer other) const noexcept
|
||||
{
|
||||
return CharacterFunctions::compareIgnoreCase (*this, other);
|
||||
}
|
||||
|
||||
/** Compares this string with another one. */
|
||||
int compareIgnoreCase (const CharPointer_UTF8 other) const noexcept
|
||||
{
|
||||
#if BEAST_WINDOWS
|
||||
return stricmp (data, other.data);
|
||||
#else
|
||||
return strcasecmp (data, other.data);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Compares this string with another one, up to a specified number of characters. */
|
||||
template <typename CharPointer>
|
||||
int compareIgnoreCaseUpTo (const CharPointer other, const int maxChars) const noexcept
|
||||
{
|
||||
return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars);
|
||||
}
|
||||
|
||||
/** Returns the character index of a substring, or -1 if it isn't found. */
|
||||
template <typename CharPointer>
|
||||
int indexOf (const CharPointer stringToFind) const noexcept
|
||||
{
|
||||
return CharacterFunctions::indexOf (*this, stringToFind);
|
||||
}
|
||||
|
||||
/** Returns the character index of a unicode character, or -1 if it isn't found. */
|
||||
int indexOf (const beast_wchar charToFind) const noexcept
|
||||
{
|
||||
return CharacterFunctions::indexOfChar (*this, charToFind);
|
||||
}
|
||||
|
||||
/** Returns the character index of a unicode character, or -1 if it isn't found. */
|
||||
int indexOf (const beast_wchar charToFind, const bool ignoreCase) const noexcept
|
||||
{
|
||||
return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind)
|
||||
: CharacterFunctions::indexOfChar (*this, charToFind);
|
||||
}
|
||||
|
||||
/** Returns true if the first character of this string is whitespace. */
|
||||
bool isWhitespace() const noexcept { return *data == ' ' || (*data <= 13 && *data >= 9); }
|
||||
/** Returns true if the first character of this string is a digit. */
|
||||
bool isDigit() const noexcept { return *data >= '0' && *data <= '9'; }
|
||||
/** Returns true if the first character of this string is a letter. */
|
||||
bool isLetter() const noexcept { return CharacterFunctions::isLetter (operator*()) != 0; }
|
||||
/** Returns true if the first character of this string is a letter or digit. */
|
||||
bool isLetterOrDigit() const noexcept { return CharacterFunctions::isLetterOrDigit (operator*()) != 0; }
|
||||
/** Returns true if the first character of this string is upper-case. */
|
||||
bool isUpperCase() const noexcept { return CharacterFunctions::isUpperCase (operator*()) != 0; }
|
||||
/** Returns true if the first character of this string is lower-case. */
|
||||
bool isLowerCase() const noexcept { return CharacterFunctions::isLowerCase (operator*()) != 0; }
|
||||
|
||||
/** Returns an upper-case version of the first character of this string. */
|
||||
beast_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase (operator*()); }
|
||||
/** Returns a lower-case version of the first character of this string. */
|
||||
beast_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase (operator*()); }
|
||||
|
||||
/** Parses this string as a 32-bit integer. */
|
||||
int getIntValue32() const noexcept { return atoi (data); }
|
||||
|
||||
/** Parses this string as a 64-bit integer. */
|
||||
std::int64_t getIntValue64() const noexcept
|
||||
{
|
||||
#if BEAST_LINUX || BEAST_ANDROID
|
||||
return atoll (data);
|
||||
#elif BEAST_WINDOWS
|
||||
return _atoi64 (data);
|
||||
#else
|
||||
return CharacterFunctions::getIntValue <std::int64_t, CharPointer_UTF8> (*this);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Parses this string as a floating point double. */
|
||||
double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); }
|
||||
|
||||
/** Returns the first non-whitespace character in the string. */
|
||||
CharPointer_UTF8 findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); }
|
||||
|
||||
/** Returns true if the given unicode character can be represented in this encoding. */
|
||||
static bool canRepresent (beast_wchar character) noexcept
|
||||
{
|
||||
return ((unsigned int) character) < (unsigned int) 0x10ffff;
|
||||
}
|
||||
|
||||
/** Returns true if this data contains a valid string in this encoding. */
|
||||
static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
|
||||
{
|
||||
while (--maxBytesToRead >= 0 && *dataToTest != 0)
|
||||
{
|
||||
const signed char byte = (signed char) *dataToTest++;
|
||||
|
||||
if (byte < 0)
|
||||
{
|
||||
std::uint8_t bit = 0x40;
|
||||
int numExtraValues = 0;
|
||||
|
||||
while ((byte & bit) != 0)
|
||||
{
|
||||
if (bit < 8)
|
||||
return false;
|
||||
|
||||
++numExtraValues;
|
||||
bit >>= 1;
|
||||
|
||||
if (bit == 8 && (numExtraValues > maxBytesToRead
|
||||
|| *CharPointer_UTF8 (dataToTest - 1) > 0x10ffff))
|
||||
return false;
|
||||
}
|
||||
|
||||
maxBytesToRead -= numExtraValues;
|
||||
if (maxBytesToRead < 0)
|
||||
return false;
|
||||
|
||||
while (--numExtraValues >= 0)
|
||||
if ((*dataToTest++ & 0xc0) != 0x80)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Atomically swaps this pointer for a new value, returning the previous value. */
|
||||
CharPointer_UTF8 atomicSwap (const CharPointer_UTF8 newValue)
|
||||
{
|
||||
return CharPointer_UTF8 (reinterpret_cast <std::atomic<CharType*>&> (data).exchange (newValue.data));
|
||||
}
|
||||
|
||||
/** These values are the byte-order mark (BOM) values for a UTF-8 stream. */
|
||||
enum
|
||||
{
|
||||
byteOrderMark1 = 0xef,
|
||||
byteOrderMark2 = 0xbb,
|
||||
byteOrderMark3 = 0xbf
|
||||
};
|
||||
|
||||
/** Returns true if the first three bytes in this pointer are the UTF8 byte-order mark (BOM).
|
||||
The pointer must not be null, and must point to at least 3 valid bytes.
|
||||
*/
|
||||
static bool isByteOrderMark (const void* possibleByteOrder) noexcept
|
||||
{
|
||||
bassert (possibleByteOrder != nullptr);
|
||||
const std::uint8_t* const c = static_cast<const std::uint8_t*> (possibleByteOrder);
|
||||
|
||||
return c[0] == (std::uint8_t) byteOrderMark1
|
||||
&& c[1] == (std::uint8_t) byteOrderMark2
|
||||
&& c[2] == (std::uint8_t) byteOrderMark3;
|
||||
}
|
||||
|
||||
private:
|
||||
CharType* data;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,598 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_STRINGS_CHARACTERFUNCTIONS_H_INCLUDED
|
||||
#define BEAST_STRINGS_CHARACTERFUNCTIONS_H_INCLUDED
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include <beast/Config.h>
|
||||
#include <beast/Memory.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
#if BEAST_WINDOWS && ! DOXYGEN
|
||||
#define BEAST_NATIVE_WCHAR_IS_UTF8 0
|
||||
#define BEAST_NATIVE_WCHAR_IS_UTF16 1
|
||||
#define BEAST_NATIVE_WCHAR_IS_UTF32 0
|
||||
#else
|
||||
/** This macro will be set to 1 if the compiler's native wchar_t is an 8-bit type. */
|
||||
#define BEAST_NATIVE_WCHAR_IS_UTF8 0
|
||||
/** This macro will be set to 1 if the compiler's native wchar_t is a 16-bit type. */
|
||||
#define BEAST_NATIVE_WCHAR_IS_UTF16 0
|
||||
/** This macro will be set to 1 if the compiler's native wchar_t is a 32-bit type. */
|
||||
#define BEAST_NATIVE_WCHAR_IS_UTF32 1
|
||||
#endif
|
||||
|
||||
#if BEAST_NATIVE_WCHAR_IS_UTF32 || DOXYGEN
|
||||
/** A platform-independent 32-bit unicode character type. */
|
||||
using beast_wchar = wchar_t;
|
||||
#else
|
||||
using beast_wchar = std::uint32_t;
|
||||
#endif
|
||||
|
||||
#ifndef DOXYGEN
|
||||
/** This macro is deprecated, but preserved for compatibility with old code. */
|
||||
#define BEAST_T(stringLiteral) (L##stringLiteral)
|
||||
#endif
|
||||
|
||||
#if BEAST_DEFINE_T_MACRO
|
||||
/** The 'T' macro is an alternative for using the "L" prefix in front of a string literal.
|
||||
|
||||
This macro is deprecated, but available for compatibility with old code if you set
|
||||
BEAST_DEFINE_T_MACRO = 1. The fastest, most portable and best way to write your string
|
||||
literals is as standard char strings, using escaped utf-8 character sequences for extended
|
||||
characters, rather than trying to store them as wide-char strings.
|
||||
*/
|
||||
#define T(stringLiteral) BEAST_T(stringLiteral)
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A collection of functions for manipulating characters and character strings.
|
||||
|
||||
Most of these methods are designed for internal use by the String and CharPointer
|
||||
classes, but some of them may be useful to call directly.
|
||||
|
||||
@see String, CharPointer_UTF8, CharPointer_UTF16, CharPointer_UTF32
|
||||
*/
|
||||
class CharacterFunctions
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Converts a character to upper-case. */
|
||||
static beast_wchar toUpperCase (beast_wchar character) noexcept;
|
||||
/** Converts a character to lower-case. */
|
||||
static beast_wchar toLowerCase (beast_wchar character) noexcept;
|
||||
|
||||
/** Checks whether a unicode character is upper-case. */
|
||||
static bool isUpperCase (beast_wchar character) noexcept;
|
||||
/** Checks whether a unicode character is lower-case. */
|
||||
static bool isLowerCase (beast_wchar character) noexcept;
|
||||
|
||||
/** Checks whether a character is whitespace. */
|
||||
static bool isWhitespace (char character) noexcept;
|
||||
/** Checks whether a character is whitespace. */
|
||||
static bool isWhitespace (beast_wchar character) noexcept;
|
||||
|
||||
/** Checks whether a character is a digit. */
|
||||
static bool isDigit (char character) noexcept;
|
||||
/** Checks whether a character is a digit. */
|
||||
static bool isDigit (beast_wchar character) noexcept;
|
||||
|
||||
/** Checks whether a character is alphabetic. */
|
||||
static bool isLetter (char character) noexcept;
|
||||
/** Checks whether a character is alphabetic. */
|
||||
static bool isLetter (beast_wchar character) noexcept;
|
||||
|
||||
/** Checks whether a character is alphabetic or numeric. */
|
||||
static bool isLetterOrDigit (char character) noexcept;
|
||||
/** Checks whether a character is alphabetic or numeric. */
|
||||
static bool isLetterOrDigit (beast_wchar character) noexcept;
|
||||
|
||||
/** Returns 0 to 16 for '0' to 'F", or -1 for characters that aren't a legal hex digit. */
|
||||
static int getHexDigitValue (beast_wchar digit) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Parses a character string to read a floating-point number.
|
||||
Note that this will advance the pointer that is passed in, leaving it at
|
||||
the end of the number.
|
||||
*/
|
||||
template <typename CharPointerType>
|
||||
static double readDoubleValue (CharPointerType& text) noexcept
|
||||
{
|
||||
double result[3] = { 0 }, accumulator[2] = { 0 };
|
||||
int exponentAdjustment[2] = { 0 }, exponentAccumulator[2] = { -1, -1 };
|
||||
int exponent = 0, decPointIndex = 0, digit = 0;
|
||||
int lastDigit = 0, numSignificantDigits = 0;
|
||||
bool isNegative = false, digitsFound = false;
|
||||
const int maxSignificantDigits = 15 + 2;
|
||||
|
||||
text = text.findEndOfWhitespace();
|
||||
beast_wchar c = *text;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '-': isNegative = true; // fall-through..
|
||||
case '+': c = *++text;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'n':
|
||||
case 'N':
|
||||
if ((text[1] == 'a' || text[1] == 'A') && (text[2] == 'n' || text[2] == 'N'))
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
case 'I':
|
||||
if ((text[1] == 'n' || text[1] == 'N') && (text[2] == 'f' || text[2] == 'F'))
|
||||
return std::numeric_limits<double>::infinity();
|
||||
break;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (text.isDigit())
|
||||
{
|
||||
lastDigit = digit;
|
||||
digit = (int) text.getAndAdvance() - '0';
|
||||
digitsFound = true;
|
||||
|
||||
if (decPointIndex != 0)
|
||||
exponentAdjustment[1]++;
|
||||
|
||||
if (numSignificantDigits == 0 && digit == 0)
|
||||
continue;
|
||||
|
||||
if (++numSignificantDigits > maxSignificantDigits)
|
||||
{
|
||||
if (digit > 5)
|
||||
++accumulator [decPointIndex];
|
||||
else if (digit == 5 && (lastDigit & 1) != 0)
|
||||
++accumulator [decPointIndex];
|
||||
|
||||
if (decPointIndex > 0)
|
||||
exponentAdjustment[1]--;
|
||||
else
|
||||
exponentAdjustment[0]++;
|
||||
|
||||
while (text.isDigit())
|
||||
{
|
||||
++text;
|
||||
if (decPointIndex == 0)
|
||||
exponentAdjustment[0]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const double maxAccumulatorValue = (double) ((std::numeric_limits<unsigned int>::max() - 9) / 10);
|
||||
if (accumulator [decPointIndex] > maxAccumulatorValue)
|
||||
{
|
||||
result [decPointIndex] = mulexp10 (result [decPointIndex], exponentAccumulator [decPointIndex])
|
||||
+ accumulator [decPointIndex];
|
||||
accumulator [decPointIndex] = 0;
|
||||
exponentAccumulator [decPointIndex] = 0;
|
||||
}
|
||||
|
||||
accumulator [decPointIndex] = accumulator[decPointIndex] * 10 + digit;
|
||||
exponentAccumulator [decPointIndex]++;
|
||||
}
|
||||
}
|
||||
else if (decPointIndex == 0 && *text == '.')
|
||||
{
|
||||
++text;
|
||||
decPointIndex = 1;
|
||||
|
||||
if (numSignificantDigits > maxSignificantDigits)
|
||||
{
|
||||
while (text.isDigit())
|
||||
++text;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result[0] = mulexp10 (result[0], exponentAccumulator[0]) + accumulator[0];
|
||||
|
||||
if (decPointIndex != 0)
|
||||
result[1] = mulexp10 (result[1], exponentAccumulator[1]) + accumulator[1];
|
||||
|
||||
c = *text;
|
||||
if ((c == 'e' || c == 'E') && digitsFound)
|
||||
{
|
||||
bool negativeExponent = false;
|
||||
|
||||
switch (*++text)
|
||||
{
|
||||
case '-': negativeExponent = true; // fall-through..
|
||||
case '+': ++text;
|
||||
}
|
||||
|
||||
while (text.isDigit())
|
||||
exponent = (exponent * 10) + ((int) text.getAndAdvance() - '0');
|
||||
|
||||
if (negativeExponent)
|
||||
exponent = -exponent;
|
||||
}
|
||||
|
||||
double r = mulexp10 (result[0], exponent + exponentAdjustment[0]);
|
||||
if (decPointIndex != 0)
|
||||
r += mulexp10 (result[1], exponent - exponentAdjustment[1]);
|
||||
|
||||
return isNegative ? -r : r;
|
||||
}
|
||||
|
||||
/** Parses a character string, to read a floating-point value. */
|
||||
template <typename CharPointerType>
|
||||
static double getDoubleValue (CharPointerType text) noexcept
|
||||
{
|
||||
return readDoubleValue (text);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Parses a character string, to read an integer value. */
|
||||
template <typename IntType, typename CharPointerType>
|
||||
static IntType getIntValue (const CharPointerType text) noexcept
|
||||
{
|
||||
IntType v = 0;
|
||||
CharPointerType s (text.findEndOfWhitespace());
|
||||
|
||||
const bool isNeg = *s == '-';
|
||||
if (isNeg)
|
||||
++s;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const beast_wchar c = s.getAndAdvance();
|
||||
|
||||
if (c >= '0' && c <= '9')
|
||||
v = v * 10 + (IntType) (c - '0');
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return isNeg ? -v : v;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Counts the number of characters in a given string, stopping if the count exceeds
|
||||
a specified limit. */
|
||||
template <typename CharPointerType>
|
||||
static size_t lengthUpTo (CharPointerType text, const size_t maxCharsToCount) noexcept
|
||||
{
|
||||
size_t len = 0;
|
||||
|
||||
while (len < maxCharsToCount && text.getAndAdvance() != 0)
|
||||
++len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/** Counts the number of characters in a given string, stopping if the count exceeds
|
||||
a specified end-pointer. */
|
||||
template <typename CharPointerType>
|
||||
static size_t lengthUpTo (CharPointerType start, const CharPointerType end) noexcept
|
||||
{
|
||||
size_t len = 0;
|
||||
|
||||
while (start < end && start.getAndAdvance() != 0)
|
||||
++len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/** Copies null-terminated characters from one string to another. */
|
||||
template <typename DestCharPointerType, typename SrcCharPointerType>
|
||||
static void copyAll (DestCharPointerType& dest, SrcCharPointerType src) noexcept
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
const beast_wchar c = src.getAndAdvance();
|
||||
|
||||
if (c == 0)
|
||||
break;
|
||||
|
||||
dest.write (c);
|
||||
}
|
||||
|
||||
dest.writeNull();
|
||||
}
|
||||
|
||||
/** Copies characters from one string to another, up to a null terminator
|
||||
or a given byte size limit. */
|
||||
template <typename DestCharPointerType, typename SrcCharPointerType>
|
||||
static size_t copyWithDestByteLimit (DestCharPointerType& dest, SrcCharPointerType src, size_t maxBytesToWrite) noexcept
|
||||
{
|
||||
typename DestCharPointerType::CharType const* const startAddress = dest.getAddress();
|
||||
size_t maxBytes = maxBytesToWrite;
|
||||
if (maxBytes >= sizeof (typename DestCharPointerType::CharType))
|
||||
maxBytes -= sizeof (typename DestCharPointerType::CharType); // (allow for a terminating null)
|
||||
else
|
||||
maxBytes = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const beast_wchar c = src.getAndAdvance();
|
||||
const size_t bytesNeeded = DestCharPointerType::getBytesRequiredFor (c);
|
||||
|
||||
if (c == 0 || maxBytes < bytesNeeded)
|
||||
break;
|
||||
maxBytes -= bytesNeeded;
|
||||
|
||||
dest.write (c);
|
||||
}
|
||||
|
||||
dest.writeNull();
|
||||
|
||||
return (size_t) getAddressDifference (dest.getAddress(), startAddress)
|
||||
+ sizeof (typename DestCharPointerType::CharType);
|
||||
}
|
||||
|
||||
/** Copies characters from one string to another, up to a null terminator
|
||||
or a given maximum number of characters. */
|
||||
template <typename DestCharPointerType, typename SrcCharPointerType>
|
||||
static void copyWithCharLimit (DestCharPointerType& dest, SrcCharPointerType src, int maxChars) noexcept
|
||||
{
|
||||
while (--maxChars > 0)
|
||||
{
|
||||
const beast_wchar c = src.getAndAdvance();
|
||||
if (c == 0)
|
||||
break;
|
||||
|
||||
dest.write (c);
|
||||
}
|
||||
|
||||
dest.writeNull();
|
||||
}
|
||||
|
||||
/** Compares two null-terminated character strings. */
|
||||
template <typename CharPointerType1, typename CharPointerType2>
|
||||
static int compare (CharPointerType1 s1, CharPointerType2 s2) noexcept
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
const int c1 = (int) s1.getAndAdvance();
|
||||
const int c2 = (int) s2.getAndAdvance();
|
||||
const int diff = c1 - c2;
|
||||
|
||||
if (diff != 0) return diff < 0 ? -1 : 1;
|
||||
if (c1 == 0) break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Compares two null-terminated character strings, up to a given number of characters. */
|
||||
template <typename CharPointerType1, typename CharPointerType2>
|
||||
static int compareUpTo (CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
|
||||
{
|
||||
while (--maxChars >= 0)
|
||||
{
|
||||
const int c1 = (int) s1.getAndAdvance();
|
||||
const int c2 = (int) s2.getAndAdvance();
|
||||
const int diff = c1 - c2;
|
||||
|
||||
if (diff != 0) return diff < 0 ? -1 : 1;
|
||||
if (c1 == 0) break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Compares two null-terminated character strings, using a case-independant match. */
|
||||
template <typename CharPointerType1, typename CharPointerType2>
|
||||
static int compareIgnoreCase (CharPointerType1 s1, CharPointerType2 s2) noexcept
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
const int c1 = (int) s1.toUpperCase(); ++s1;
|
||||
const int c2 = (int) s2.toUpperCase(); ++s2;
|
||||
const int diff = c1 - c2;
|
||||
|
||||
if (diff != 0) return diff < 0 ? -1 : 1;
|
||||
if (c1 == 0) break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Compares two null-terminated character strings, using a case-independent match. */
|
||||
template <typename CharPointerType1, typename CharPointerType2>
|
||||
static int compareIgnoreCaseUpTo (CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
|
||||
{
|
||||
while (--maxChars >= 0)
|
||||
{
|
||||
const int c1 = (int) s1.toUpperCase(); ++s1;
|
||||
const int c2 = (int) s2.toUpperCase(); ++s2;
|
||||
const int diff = c1 - c2;
|
||||
|
||||
if (diff != 0) return diff < 0 ? -1 : 1;
|
||||
if (c1 == 0) break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Finds the character index of a given substring in another string.
|
||||
Returns -1 if the substring is not found.
|
||||
*/
|
||||
template <typename CharPointerType1, typename CharPointerType2>
|
||||
static int indexOf (CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept
|
||||
{
|
||||
int index = 0;
|
||||
const int substringLength = (int) substringToLookFor.length();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (textToSearch.compareUpTo (substringToLookFor, substringLength) == 0)
|
||||
return index;
|
||||
|
||||
if (textToSearch.getAndAdvance() == 0)
|
||||
return -1;
|
||||
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a pointer to the first occurrence of a substring in a string.
|
||||
If the substring is not found, this will return a pointer to the string's
|
||||
null terminator.
|
||||
*/
|
||||
template <typename CharPointerType1, typename CharPointerType2>
|
||||
static CharPointerType1 find (CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept
|
||||
{
|
||||
const int substringLength = (int) substringToLookFor.length();
|
||||
|
||||
while (textToSearch.compareUpTo (substringToLookFor, substringLength) != 0
|
||||
&& ! textToSearch.isEmpty())
|
||||
++textToSearch;
|
||||
|
||||
return textToSearch;
|
||||
}
|
||||
|
||||
/** Finds the character index of a given substring in another string, using
|
||||
a case-independent match.
|
||||
Returns -1 if the substring is not found.
|
||||
*/
|
||||
template <typename CharPointerType1, typename CharPointerType2>
|
||||
static int indexOfIgnoreCase (CharPointerType1 haystack, const CharPointerType2 needle) noexcept
|
||||
{
|
||||
int index = 0;
|
||||
const int needleLength = (int) needle.length();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (haystack.compareIgnoreCaseUpTo (needle, needleLength) == 0)
|
||||
return index;
|
||||
|
||||
if (haystack.getAndAdvance() == 0)
|
||||
return -1;
|
||||
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
/** Finds the character index of a given character in another string.
|
||||
Returns -1 if the character is not found.
|
||||
*/
|
||||
template <typename Type>
|
||||
static int indexOfChar (Type text, const beast_wchar charToFind) noexcept
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (! text.isEmpty())
|
||||
{
|
||||
if (text.getAndAdvance() == charToFind)
|
||||
return i;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Finds the character index of a given character in another string, using
|
||||
a case-independent match.
|
||||
Returns -1 if the character is not found.
|
||||
*/
|
||||
template <typename Type>
|
||||
static int indexOfCharIgnoreCase (Type text, beast_wchar charToFind) noexcept
|
||||
{
|
||||
charToFind = CharacterFunctions::toLowerCase (charToFind);
|
||||
int i = 0;
|
||||
|
||||
while (! text.isEmpty())
|
||||
{
|
||||
if (text.toLowerCase() == charToFind)
|
||||
return i;
|
||||
|
||||
++text;
|
||||
++i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Returns a pointer to the first non-whitespace character in a string.
|
||||
If the string contains only whitespace, this will return a pointer
|
||||
to its null terminator.
|
||||
*/
|
||||
template <typename Type>
|
||||
static Type findEndOfWhitespace (const Type& text) noexcept
|
||||
{
|
||||
Type p (text);
|
||||
|
||||
while (p.isWhitespace())
|
||||
++p;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/** Returns a pointer to the first character in the string which is found in
|
||||
the breakCharacters string.
|
||||
*/
|
||||
template <typename Type>
|
||||
static Type findEndOfToken (const Type& text, const Type& breakCharacters, const Type& quoteCharacters)
|
||||
{
|
||||
Type t (text);
|
||||
beast_wchar currentQuoteChar = 0;
|
||||
|
||||
while (! t.isEmpty())
|
||||
{
|
||||
const beast_wchar c = t.getAndAdvance();
|
||||
|
||||
if (currentQuoteChar == 0 && breakCharacters.indexOf (c) >= 0)
|
||||
{
|
||||
--t;
|
||||
break;
|
||||
}
|
||||
|
||||
if (quoteCharacters.indexOf (c) >= 0)
|
||||
{
|
||||
if (currentQuoteChar == 0)
|
||||
currentQuoteChar = c;
|
||||
else if (currentQuoteChar == c)
|
||||
currentQuoteChar = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
private:
|
||||
static double mulexp10 (const double value, int exponent) noexcept;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_STRINGS_NEWLINE_H_INCLUDED
|
||||
#define BEAST_STRINGS_NEWLINE_H_INCLUDED
|
||||
|
||||
#include <beast/Config.h>
|
||||
|
||||
#include <beast/strings/String.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/** This class is used for represent a new-line character sequence.
|
||||
|
||||
To write a new-line to a stream, you can use the predefined 'newLine' variable, e.g.
|
||||
@code
|
||||
myOutputStream << "Hello World" << newLine << newLine;
|
||||
@endcode
|
||||
|
||||
The exact character sequence that will be used for the new-line can be set and
|
||||
retrieved with OutputStream::setNewLineString() and OutputStream::getNewLineString().
|
||||
*/
|
||||
class NewLine
|
||||
{
|
||||
public:
|
||||
/** Returns the default new-line sequence that the library uses.
|
||||
@see OutputStream::setNewLineString()
|
||||
*/
|
||||
static const char* getDefault() noexcept { return "\r\n"; }
|
||||
|
||||
/** Returns the default new-line sequence that the library uses.
|
||||
@see getDefault()
|
||||
*/
|
||||
operator String() const { return getDefault(); }
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** A predefined object representing a new-line, which can be written to a string or stream.
|
||||
|
||||
To write a new-line to a stream, you can use the predefined 'newLine' variable like this:
|
||||
@code
|
||||
myOutputStream << "Hello World" << newLine << newLine;
|
||||
@endcode
|
||||
*/
|
||||
extern NewLine newLine;
|
||||
|
||||
//==============================================================================
|
||||
/** Writes a new-line sequence to a string.
|
||||
You can use the predefined object 'newLine' to invoke this, e.g.
|
||||
@code
|
||||
myString << "Hello World" << newLine << newLine;
|
||||
@endcode
|
||||
*/
|
||||
String& operator<< (String& string1, const NewLine&);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,63 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_STRINGS_STRINGCHARPOINTERTYPE_H_INCLUDED
|
||||
#define BEAST_STRINGS_STRINGCHARPOINTERTYPE_H_INCLUDED
|
||||
|
||||
#include <beast/Config.h>
|
||||
#include <beast/strings/CharPointer_UTF8.h>
|
||||
#include <beast/strings/CharPointer_UTF16.h>
|
||||
#include <beast/strings/CharPointer_UTF32.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** This is the character encoding type used internally to store the string.
|
||||
|
||||
By setting the value of BEAST_STRING_UTF_TYPE to 8, 16, or 32, you can change the
|
||||
internal storage format of the String class. UTF-8 uses the least space (if your strings
|
||||
contain few extended characters), but call operator[] involves iterating the string to find
|
||||
the required index. UTF-32 provides instant random access to its characters, but uses 4 bytes
|
||||
per character to store them. UTF-16 uses more space than UTF-8 and is also slow to index,
|
||||
but is the native wchar_t format used in Windows.
|
||||
|
||||
It doesn't matter too much which format you pick, because the toUTF8(), toUTF16() and
|
||||
toUTF32() methods let you access the string's content in any of the other formats.
|
||||
*/
|
||||
#if (BEAST_STRING_UTF_TYPE == 32)
|
||||
using StringCharPointerType = CharPointer_UTF32;
|
||||
|
||||
#elif (BEAST_STRING_UTF_TYPE == 16)
|
||||
using StringCharPointerType = CharPointer_UTF16;
|
||||
|
||||
#elif (BEAST_STRING_UTF_TYPE == 8)
|
||||
using StringCharPointerType = CharPointer_UTF8;
|
||||
|
||||
#else
|
||||
#error "You must set the value of BEAST_STRING_UTF_TYPE to be either 8, 16, or 32!"
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,177 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.beast.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_STRINGS_STRINGFROMNUMBER_H_INCLUDED
|
||||
#define BEAST_STRINGS_STRINGFROMNUMBER_H_INCLUDED
|
||||
|
||||
#include <beast/Config.h>
|
||||
#include <beast/Arithmetic.h>
|
||||
|
||||
#include <beast/strings/StringCharPointerType.h>
|
||||
|
||||
#include <limits>
|
||||
#include <ostream>
|
||||
#include <streambuf>
|
||||
|
||||
namespace beast {
|
||||
|
||||
// VFALCO TODO Put this in namespace detail
|
||||
//
|
||||
class NumberToStringConverters
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
charsNeededForInt = 32,
|
||||
charsNeededForDouble = 48
|
||||
};
|
||||
|
||||
// pass in a pointer to the END of a buffer..
|
||||
template <typename Type>
|
||||
static char* printDigits (char* t, Type v) noexcept
|
||||
{
|
||||
*--t = 0;
|
||||
do
|
||||
{
|
||||
*--t = '0' + (char) (v % 10);
|
||||
v /= 10;
|
||||
}
|
||||
while (v > 0);
|
||||
return t;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4127) // conditional expression is constant
|
||||
#pragma warning (disable: 4146) // unary minus operator applied to unsigned type, result still unsigned
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wtautological-compare"
|
||||
#endif
|
||||
// pass in a pointer to the END of a buffer..
|
||||
template <typename IntegerType>
|
||||
static char* numberToString (char* t, IntegerType const n) noexcept
|
||||
{
|
||||
if (std::numeric_limits <IntegerType>::is_signed)
|
||||
{
|
||||
if (n >= 0)
|
||||
return printDigits (t, static_cast <std::uint64_t> (n));
|
||||
|
||||
// NB: this needs to be careful not to call
|
||||
// -std::numeric_limits<std::int64_t>::min(),
|
||||
// which has undefined behaviour
|
||||
//
|
||||
t = printDigits (t, static_cast <std::uint64_t> (-(n + 1)) + 1);
|
||||
*--t = '-';
|
||||
return t;
|
||||
}
|
||||
return printDigits (t, n);
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
struct StackArrayStream : public std::basic_streambuf <char, std::char_traits <char> >
|
||||
{
|
||||
explicit StackArrayStream (char* d)
|
||||
{
|
||||
imbue (std::locale::classic());
|
||||
setp (d, d + charsNeededForDouble);
|
||||
}
|
||||
|
||||
size_t writeDouble (double n, int numDecPlaces)
|
||||
{
|
||||
{
|
||||
std::ostream o (this);
|
||||
|
||||
if (numDecPlaces > 0)
|
||||
o.precision ((std::streamsize) numDecPlaces);
|
||||
|
||||
o << n;
|
||||
}
|
||||
|
||||
return (size_t) (pptr() - pbase());
|
||||
}
|
||||
};
|
||||
|
||||
static char* doubleToString (char* buffer,
|
||||
const int numChars, double n, int numDecPlaces, size_t& len) noexcept
|
||||
{
|
||||
if (numDecPlaces > 0 && numDecPlaces < 7 && n > -1.0e20 && n < 1.0e20)
|
||||
{
|
||||
char* const end = buffer + numChars;
|
||||
char* t = end;
|
||||
std::int64_t v = (std::int64_t) (pow (10.0, numDecPlaces) * std::abs (n) + 0.5);
|
||||
*--t = (char) 0;
|
||||
|
||||
while (numDecPlaces >= 0 || v > 0)
|
||||
{
|
||||
if (numDecPlaces == 0)
|
||||
*--t = '.';
|
||||
|
||||
*--t = (char) ('0' + (v % 10));
|
||||
|
||||
v /= 10;
|
||||
--numDecPlaces;
|
||||
}
|
||||
|
||||
if (n < 0)
|
||||
*--t = '-';
|
||||
|
||||
len = (size_t) (end - t - 1);
|
||||
return t;
|
||||
}
|
||||
|
||||
StackArrayStream strm (buffer);
|
||||
len = strm.writeDouble (n, numDecPlaces);
|
||||
bassert (len <= charsNeededForDouble);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static StringCharPointerType createFromFixedLength (
|
||||
const char* const src, const size_t numChars);
|
||||
|
||||
template <typename IntegerType>
|
||||
static StringCharPointerType createFromInteger (const IntegerType number)
|
||||
{
|
||||
char buffer [charsNeededForInt];
|
||||
char* const end = buffer + numElementsInArray (buffer);
|
||||
char* const start = numberToString (end, number);
|
||||
return createFromFixedLength (start, (size_t) (end - start - 1));
|
||||
}
|
||||
|
||||
static StringCharPointerType createFromDouble (
|
||||
const double number, const int numberOfDecimalPlaces)
|
||||
{
|
||||
char buffer [charsNeededForDouble];
|
||||
size_t len;
|
||||
char* const start = doubleToString (buffer, numElementsInArray (buffer), (double) number, numberOfDecimalPlaces, len);
|
||||
return createFromFixedLength (start, len);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user