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:
Nik Bougalis
2016-01-20 12:32:02 -08:00
parent 77955c74bc
commit de4d872b7a
121 changed files with 78 additions and 19484 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -218,7 +218,7 @@ private:
}
// VFALCO TODO IPv6 support
bassertfalse;
assert(false);
return boost::asio::ip::udp::endpoint (
boost::asio::ip::address_v6 (), 0);
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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));
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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")

View File

@@ -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
{

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
{

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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()
{

View File

@@ -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

View File

@@ -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()
{

View File

@@ -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

View File

@@ -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

View File

@@ -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{};
}

View File

@@ -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()];
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -29,12 +29,6 @@ void outputDebugString (std::string const& text)
OutputDebugStringA ((text + "\n").c_str ());
}
//==============================================================================
bool beast_isRunningUnderDebugger()
{
return IsDebuggerPresent() != FALSE;
}
//==============================================================================
std::string getComputerName()
{

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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();

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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.

View File

@@ -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

View File

@@ -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 ()

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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;
}
}

View File

@@ -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());
}
};

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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