mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
beast cleanup and tidying:
* Replace custom types with C++11 <cstdint> types * Fix sqlite integer intos and uses * Fix String implicit integer constructors * Escape the enclosing namespace in sqdb * Replace contract checks with assert * Make many header files compile independently * Remove the dependence on beast_core.h in many places * Remove unused or obsolete classes and functions * Remove unused or obsolete macros * Remove unused network functions and files * Remove unused or obsolete classes: - ChildProcess - HighResolutionTimer - InterProcessLock - Throw - TrackedMutex - UntrackedMutex - XmlDocument - XmlElement
This commit is contained in:
@@ -35,13 +35,13 @@ class FixedInputBuffer
|
||||
protected:
|
||||
struct CtorParams
|
||||
{
|
||||
CtorParams (uint8 const* begin_, std::size_t bytes_)
|
||||
CtorParams (std::uint8_t const* begin_, std::size_t bytes_)
|
||||
: begin (begin_)
|
||||
, bytes (bytes_)
|
||||
{
|
||||
}
|
||||
|
||||
uint8 const* begin;
|
||||
std::uint8_t const* begin;
|
||||
std::size_t bytes;
|
||||
};
|
||||
|
||||
@@ -107,7 +107,7 @@ public:
|
||||
return read_impl (sizeof (T), t) != nullptr;
|
||||
}
|
||||
|
||||
uint8 operator[] (std::size_t index) const noexcept
|
||||
std::uint8_t operator[] (std::size_t index) const noexcept
|
||||
{
|
||||
bassert (index >= 0 && index < size ());
|
||||
return m_iter [index];
|
||||
@@ -153,9 +153,9 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 const* m_begin;
|
||||
uint8 const* m_iter;
|
||||
uint8 const* m_end;
|
||||
std::uint8_t const* m_begin;
|
||||
std::uint8_t const* m_iter;
|
||||
std::uint8_t const* m_end;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -170,7 +170,7 @@ protected:
|
||||
SizedCtorParams (ConstBufferSequence const& buffers, Storage& storage)
|
||||
{
|
||||
boost::asio::mutable_buffer buffer (boost::asio::buffer (storage));
|
||||
data = boost::asio::buffer_cast <uint8 const*> (buffer);
|
||||
data = boost::asio::buffer_cast <std::uint8_t const*> (buffer);
|
||||
bytes = boost::asio::buffer_copy (buffer, buffers);
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ protected:
|
||||
return CtorParams (data, bytes);
|
||||
}
|
||||
|
||||
uint8 const* data;
|
||||
std::uint8_t const* data;
|
||||
std::size_t bytes;
|
||||
};
|
||||
|
||||
@@ -191,7 +191,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
boost::array <uint8, Bytes> m_storage;
|
||||
boost::array <std::uint8_t, Bytes> m_storage;
|
||||
boost::asio::mutable_buffer m_buffer;
|
||||
};
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "../../../beast/asio/placeholders.h"
|
||||
#include "../../../beast/unit_test/suite.h"
|
||||
|
||||
#include "../../../beast/cxx14/memory.h" // <memory>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
@@ -190,7 +192,7 @@ public:
|
||||
|
||||
String m_get_string;
|
||||
WaitableEvent m_done;
|
||||
ScopedPointer <abstract_socket> m_stream;
|
||||
std::unique_ptr <abstract_socket> m_stream;
|
||||
|
||||
struct State
|
||||
{
|
||||
@@ -387,7 +389,8 @@ public:
|
||||
if (m_url.scheme () == "https")
|
||||
{
|
||||
typedef boost::asio::ssl::stream <socket&> ssl_stream;
|
||||
m_stream = new socket_wrapper <ssl_stream> (m_socket, m_context);
|
||||
m_stream = std::make_unique <
|
||||
socket_wrapper <ssl_stream>> (m_socket, m_context);
|
||||
/*
|
||||
m_stream->set_verify_mode (
|
||||
boost::asio::ssl::verify_peer |
|
||||
@@ -399,7 +402,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
m_stream = new socket_wrapper <socket&> (m_socket);
|
||||
m_stream = std::make_unique <socket_wrapper <socket&>> (m_socket);
|
||||
handle_handshake (ec);
|
||||
}
|
||||
|
||||
@@ -637,7 +640,7 @@ public:
|
||||
|
||||
void testSync (String const& s, double timeoutSeconds)
|
||||
{
|
||||
ScopedPointer <HTTPClientBase> client (
|
||||
std::unique_ptr <HTTPClientBase> client (
|
||||
HTTPClientBase::New (Journal(), timeoutSeconds));
|
||||
|
||||
HTTPClientBase::result_type const& result (
|
||||
@@ -649,7 +652,7 @@ public:
|
||||
void testAsync (String const& s, double timeoutSeconds)
|
||||
{
|
||||
IoServiceThread t;
|
||||
ScopedPointer <HTTPClientBase> client (
|
||||
std::unique_ptr <HTTPClientBase> client (
|
||||
HTTPClientBase::New (Journal(), timeoutSeconds));
|
||||
|
||||
client->async_get (t.get_io_service (), ParsedURL (s).url (),
|
||||
|
||||
@@ -79,7 +79,7 @@ public:
|
||||
|
||||
protected:
|
||||
Type m_type;
|
||||
ScopedPointer <HTTPParserImpl> m_impl;
|
||||
std::unique_ptr <HTTPParserImpl> m_impl;
|
||||
SharedPtr <HTTPRequest> m_request;
|
||||
SharedPtr <HTTPResponse> m_response;
|
||||
};
|
||||
|
||||
@@ -50,8 +50,8 @@ public:
|
||||
IPv4Address sourceAddress;
|
||||
IPv4Address destAddress;
|
||||
|
||||
uint16 sourcePort;
|
||||
uint16 destPort;
|
||||
std::uint16_t sourcePort;
|
||||
std::uint16_t destPort;
|
||||
};
|
||||
|
||||
explicit HandshakeDetectLogicPROXY (arg_type const&)
|
||||
|
||||
@@ -27,14 +27,14 @@ namespace asio {
|
||||
//
|
||||
// http://tools.ietf.org/html/rfc5246#appendix-E.2
|
||||
//
|
||||
// uint8 V2CipherSpec[3];
|
||||
// std::uint8_t V2CipherSpec[3];
|
||||
// struct {
|
||||
// uint16 msg_length;
|
||||
// uint8 msg_type;
|
||||
// std::uint16_t msg_length;
|
||||
// std::uint8_t msg_type;
|
||||
// Version version; Should be 'ProtocolVersion'?
|
||||
// uint16 cipher_spec_length;
|
||||
// uint16 session_id_length;
|
||||
// uint16 challenge_length;
|
||||
// std::uint16_t cipher_spec_length;
|
||||
// std::uint16_t session_id_length;
|
||||
// std::uint16_t challenge_length;
|
||||
// ...
|
||||
//
|
||||
class HandshakeDetectLogicSSL2 : public HandshakeDetectLogic
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
FixedInputBufferSize <bytesNeeded> in (buffer);
|
||||
|
||||
{
|
||||
uint8 byte;
|
||||
std::uint8_t byte;
|
||||
if (! in.peek (&byte))
|
||||
return;
|
||||
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
// The remaining bits contain the
|
||||
// length of the following data in bytes.
|
||||
//
|
||||
uint16 msg_length;
|
||||
std::uint16_t msg_length;
|
||||
if (! in.readNetworkInteger(&msg_length))
|
||||
return;
|
||||
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
if (msg_length < 9)
|
||||
return fail ();
|
||||
|
||||
uint8 msg_type;
|
||||
std::uint8_t msg_type;
|
||||
if (! in.read (&msg_type))
|
||||
return;
|
||||
|
||||
|
||||
@@ -56,10 +56,10 @@ public:
|
||||
template <typename ConstBufferSequence>
|
||||
void analyze (ConstBufferSequence const& buffer)
|
||||
{
|
||||
uint16 version;
|
||||
std::uint16_t version;
|
||||
FixedInputBufferSize <bytesNeeded> in (buffer);
|
||||
|
||||
uint8 msg_type;
|
||||
std::uint8_t msg_type;
|
||||
if (! in.read (&msg_type))
|
||||
return;
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
return;
|
||||
version = fromNetworkByteOrder (version);
|
||||
|
||||
uint16 length;
|
||||
std::uint16_t length;
|
||||
if (! in.read (&length))
|
||||
return;
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ struct Get <Digit>
|
||||
// An unsigned 32 bit number expressed as a string
|
||||
struct UInt32Str
|
||||
{
|
||||
uint32 value;
|
||||
std::uint32_t value;
|
||||
};
|
||||
|
||||
template <>
|
||||
@@ -239,7 +239,7 @@ struct Get <UInt32Str>
|
||||
static State func (Input in, UInt32Str& t)
|
||||
{
|
||||
State state;
|
||||
uint32 value (0);
|
||||
std::uint32_t value (0);
|
||||
|
||||
Digit digit;
|
||||
// have to have at least one digit
|
||||
@@ -266,7 +266,7 @@ struct Get <UInt32Str>
|
||||
if (value == 0)
|
||||
return State::fail;
|
||||
|
||||
uint32 newValue = (value * 10) + digit.value;
|
||||
std::uint32_t newValue = (value * 10) + digit.value;
|
||||
|
||||
// overflow
|
||||
if (newValue < value)
|
||||
@@ -284,7 +284,7 @@ struct Get <UInt32Str>
|
||||
// An unsigned 16 bit number expressed as a string
|
||||
struct UInt16Str
|
||||
{
|
||||
uint16 value;
|
||||
std::uint16_t value;
|
||||
};
|
||||
|
||||
template <>
|
||||
@@ -298,7 +298,7 @@ struct Get <UInt16Str>
|
||||
{
|
||||
if (v.value <= 65535)
|
||||
{
|
||||
t.value = uint16(v.value);
|
||||
t.value = std::uint16_t(v.value);
|
||||
return State::pass;
|
||||
}
|
||||
return State::fail;
|
||||
@@ -312,7 +312,7 @@ struct Get <UInt16Str>
|
||||
// An unsigned 8 bit number expressed as a string
|
||||
struct UInt8Str
|
||||
{
|
||||
uint8 value;
|
||||
std::uint8_t value;
|
||||
};
|
||||
|
||||
template <>
|
||||
@@ -326,7 +326,7 @@ struct Get <UInt8Str>
|
||||
{
|
||||
if (v.value <= 255)
|
||||
{
|
||||
t.value = uint8(v.value);
|
||||
t.value = std::uint8_t(v.value);
|
||||
return State::pass;
|
||||
}
|
||||
return State::fail;
|
||||
@@ -340,7 +340,7 @@ struct Get <UInt8Str>
|
||||
// An dotted IPv4 address
|
||||
struct IPv4Address
|
||||
{
|
||||
uint8 value [4];
|
||||
std::uint8_t value [4];
|
||||
|
||||
String toString () const
|
||||
{
|
||||
|
||||
@@ -157,18 +157,12 @@
|
||||
#include "text/StringArray.cpp"
|
||||
#include "text/StringPairArray.cpp"
|
||||
|
||||
#include "thread/impl/TrackedMutex.cpp"
|
||||
#include "thread/DeadlineTimer.cpp"
|
||||
#include "thread/Workers.cpp"
|
||||
|
||||
#include "threads/ChildProcess.cpp"
|
||||
|
||||
#include "time/AtExitHook.cpp"
|
||||
#include "time/Time.cpp"
|
||||
|
||||
#include "xml/XmlDocument.cpp"
|
||||
#include "xml/XmlElement.cpp"
|
||||
|
||||
#if BEAST_MAC || BEAST_IOS
|
||||
#include "native/osx_ObjCHelpers.h"
|
||||
#endif
|
||||
@@ -183,7 +177,6 @@
|
||||
|
||||
#if BEAST_MAC || BEAST_IOS
|
||||
#include "native/mac_Files.mm"
|
||||
#include "native/mac_Network.mm"
|
||||
#include "native/mac_Strings.mm"
|
||||
#include "native/mac_SystemStats.mm"
|
||||
#include "native/mac_Threads.mm"
|
||||
@@ -191,34 +184,28 @@
|
||||
#elif BEAST_WINDOWS
|
||||
#include "native/win32_ComSmartPtr.h"
|
||||
#include "native/win32_Files.cpp"
|
||||
#include "native/win32_Network.cpp"
|
||||
#include "native/win32_Registry.cpp"
|
||||
#include "native/win32_SystemStats.cpp"
|
||||
#include "native/win32_Threads.cpp"
|
||||
|
||||
#elif BEAST_LINUX
|
||||
#include "native/linux_Files.cpp"
|
||||
#include "native/linux_Network.cpp"
|
||||
#include "native/linux_SystemStats.cpp"
|
||||
#include "native/linux_Threads.cpp"
|
||||
|
||||
#elif BEAST_BSD
|
||||
#include "native/bsd_Files.cpp"
|
||||
#include "native/bsd_Network.cpp"
|
||||
#include "native/bsd_SystemStats.cpp"
|
||||
#include "native/bsd_Threads.cpp"
|
||||
|
||||
#elif BEAST_ANDROID
|
||||
#include "native/android_Files.cpp"
|
||||
#include "native/android_Misc.cpp"
|
||||
#include "native/android_Network.cpp"
|
||||
#include "native/android_SystemStats.cpp"
|
||||
#include "native/android_Threads.cpp"
|
||||
|
||||
#endif
|
||||
|
||||
#include "threads/HighResolutionTimer.cpp"
|
||||
|
||||
// Has to be outside the beast namespace
|
||||
extern "C" {
|
||||
void beast_reportFatalError (char const* message, char const* fileName, int lineNumber)
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// New header-only library modeled more closely according to boost
|
||||
#include "../../beast/CStdInt.h"
|
||||
#include "../../beast/SmartPtr.h"
|
||||
#include "../../beast/StaticAssert.h"
|
||||
#include "../../beast/Uncopyable.h"
|
||||
@@ -74,12 +73,11 @@ class OutputStream;
|
||||
class FileInputStream;
|
||||
class FileOutputStream;
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
// Order matters, since headers don't have their own #include lines.
|
||||
// Add new includes to the bottom.
|
||||
|
||||
#include "diagnostic/Throw.h"
|
||||
#include "system/Functional.h"
|
||||
|
||||
#include "time/AtExitHook.h"
|
||||
@@ -143,14 +141,12 @@ class FileOutputStream;
|
||||
#include "files/File.h"
|
||||
|
||||
#include "thread/MutexTraits.h"
|
||||
#include "thread/TrackedMutex.h"
|
||||
#include "diagnostic/FatalError.h"
|
||||
#include "text/LexicalCast.h"
|
||||
#include "maths/Math.h"
|
||||
#include "logging/Logger.h"
|
||||
#include "containers/LinkedListPointer.h"
|
||||
#include "maths/Random.h"
|
||||
#include "containers/OwnedArray.h"
|
||||
#include "text/StringPairArray.h"
|
||||
#include "containers/ScopedValueSetter.h"
|
||||
#include "maths/Range.h"
|
||||
@@ -171,13 +167,8 @@ class FileOutputStream;
|
||||
|
||||
#include "system/SystemStats.h"
|
||||
#include "diagnostic/SemanticVersion.h"
|
||||
#include "threads/ChildProcess.h"
|
||||
#include "threads/DynamicLibrary.h"
|
||||
#include "threads/HighResolutionTimer.h"
|
||||
#include "threads/InterProcessLock.h"
|
||||
#include "threads/Process.h"
|
||||
#include "xml/XmlDocument.h"
|
||||
#include "xml/XmlElement.h"
|
||||
#include "diagnostic/UnitTestUtilities.h"
|
||||
|
||||
#include "diagnostic/MeasureFunctionCallTime.h"
|
||||
|
||||
@@ -24,8 +24,11 @@
|
||||
#ifndef BEAST_ARRAY_H_INCLUDED
|
||||
#define BEAST_ARRAY_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
#include "ArrayAllocationBase.h"
|
||||
#include "ElementComparator.h"
|
||||
#include "../threads/CriticalSection.h"
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
@@ -39,17 +42,13 @@ namespace beast
|
||||
- it must be able to be relocated in memory by a memcpy without this causing any problems - so
|
||||
objects whose functionality relies on external pointers or references to themselves can be used.
|
||||
|
||||
You can of course have an array of pointers to any kind of object, e.g. Array <MyClass*>, but if
|
||||
you do this, the array doesn't take any ownership of the objects - see the OwnedArray class or the
|
||||
SharedObjectArray class for more powerful ways of holding lists of objects.
|
||||
|
||||
For holding lists of strings, you can use Array\<String\>, but it's usually better to use the
|
||||
specialised class StringArray, which provides more useful functions.
|
||||
|
||||
To make all the array's methods thread-safe, pass in "CriticalSection" as the templated
|
||||
TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.
|
||||
|
||||
@see OwnedArray, SharedObjectArray, StringArray, CriticalSection
|
||||
@see SharedObjectArray, StringArray, CriticalSection
|
||||
*/
|
||||
template <typename ElementType,
|
||||
typename TypeOfCriticalSectionToUse = DummyCriticalSection,
|
||||
@@ -57,7 +56,7 @@ template <typename ElementType,
|
||||
class Array
|
||||
{
|
||||
private:
|
||||
typedef PARAMETER_TYPE (ElementType) ParameterType;
|
||||
typedef ElementType ParameterType;
|
||||
|
||||
public:
|
||||
//==============================================================================
|
||||
@@ -1055,6 +1054,6 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_ARRAY_H_INCLUDED
|
||||
|
||||
@@ -24,8 +24,9 @@
|
||||
#ifndef BEAST_ARRAYALLOCATIONBASE_H_INCLUDED
|
||||
#define BEAST_ARRAYALLOCATIONBASE_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
#include "../../../beast/HeapBlock.h"
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
@@ -37,7 +38,7 @@ namespace beast
|
||||
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, OwnedArray, SharedObjectArray
|
||||
@see Array, SharedObjectArray
|
||||
*/
|
||||
template <class ElementType, class TypeOfCriticalSectionToUse>
|
||||
class ArrayAllocationBase
|
||||
@@ -129,6 +130,6 @@ public:
|
||||
int numAllocated;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_ARRAYALLOCATIONBASE_H_INCLUDED
|
||||
|
||||
@@ -179,7 +179,7 @@ template <class ElementType>
|
||||
class DefaultElementComparator
|
||||
{
|
||||
private:
|
||||
typedef PARAMETER_TYPE (ElementType) ParameterType;
|
||||
typedef ElementType ParameterType;
|
||||
|
||||
public:
|
||||
static int compareElements (ParameterType first, ParameterType second)
|
||||
@@ -188,7 +188,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -360,6 +360,6 @@ private:
|
||||
ObjectType* item;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_LINKEDLISTPOINTER_H_INCLUDED
|
||||
|
||||
@@ -1,893 +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_OWNEDARRAY_H_INCLUDED
|
||||
#define BEAST_OWNEDARRAY_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/** An array designed for holding objects.
|
||||
|
||||
This holds a list of pointers to objects, and will automatically
|
||||
delete the objects when they are removed from the array, or when the
|
||||
array is itself deleted.
|
||||
|
||||
Declare it in the form: OwnedArray<MyObjectClass>
|
||||
|
||||
..and then add new objects, e.g. myOwnedArray.add (new MyObjectClass());
|
||||
|
||||
After adding objects, they are 'owned' by the array and will be deleted when
|
||||
removed or replaced.
|
||||
|
||||
To make all the array's methods thread-safe, pass in "CriticalSection" as the templated
|
||||
TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.
|
||||
|
||||
@see Array, SharedObjectArray, StringArray, CriticalSection
|
||||
*/
|
||||
template <class ObjectClass,
|
||||
class TypeOfCriticalSectionToUse = DummyCriticalSection>
|
||||
|
||||
class OwnedArray
|
||||
: LeakChecked <OwnedArray <ObjectClass, TypeOfCriticalSectionToUse> >
|
||||
, public Uncopyable
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty array. */
|
||||
OwnedArray() noexcept
|
||||
: numUsed (0)
|
||||
{
|
||||
}
|
||||
|
||||
/** Deletes the array and also deletes any objects inside it.
|
||||
|
||||
To get rid of the array without deleting its objects, use its
|
||||
clear (false) method before deleting it.
|
||||
*/
|
||||
~OwnedArray()
|
||||
{
|
||||
deleteAllObjects();
|
||||
}
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
OwnedArray (OwnedArray&& other) noexcept
|
||||
: data (static_cast <ArrayAllocationBase <ObjectClass*, TypeOfCriticalSectionToUse>&&> (other.data)),
|
||||
numUsed (other.numUsed)
|
||||
{
|
||||
other.numUsed = 0;
|
||||
}
|
||||
|
||||
OwnedArray& operator= (OwnedArray&& other) noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
deleteAllObjects();
|
||||
|
||||
data = static_cast <ArrayAllocationBase <ObjectClass*, TypeOfCriticalSectionToUse>&&> (other.data);
|
||||
numUsed = other.numUsed;
|
||||
other.numUsed = 0;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
/** Clears the array, optionally deleting the objects inside it first. */
|
||||
void clear (bool deleteObjects = true)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (deleteObjects)
|
||||
deleteAllObjects();
|
||||
|
||||
data.setAllocatedSize (0);
|
||||
numUsed = 0;
|
||||
}
|
||||
|
||||
/** Clears the array, optionally deleting the objects inside it first.
|
||||
|
||||
The array's allocated storage is preserved.
|
||||
|
||||
@see clear
|
||||
*/
|
||||
void clearQuick(bool deleteObjects = true)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (deleteObjects)
|
||||
deleteAllObjects();
|
||||
|
||||
numUsed = 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the number of items currently in the array.
|
||||
@see operator[]
|
||||
*/
|
||||
inline int size() const noexcept
|
||||
{
|
||||
return numUsed;
|
||||
}
|
||||
|
||||
/** Returns a pointer to the object at this index in the array.
|
||||
|
||||
If the index is out-of-range, this will return a null pointer, (and
|
||||
it could be null anyway, because it's ok for the array to hold null
|
||||
pointers as well as objects).
|
||||
|
||||
@see getUnchecked
|
||||
*/
|
||||
inline ObjectClass* operator[] (const int index) const noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
if (isPositiveAndBelow (index, numUsed))
|
||||
{
|
||||
bassert (data.elements != nullptr);
|
||||
return data.elements [index];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/** Returns a pointer to the object at this index in the array, without checking whether the index is in-range.
|
||||
|
||||
This is a faster and less safe version of operator[] which doesn't check the index passed in, so
|
||||
it can be used when you're sure the index is always going to be legal.
|
||||
*/
|
||||
inline ObjectClass* getUnchecked (const int index) const noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
bassert (isPositiveAndBelow (index, numUsed) && data.elements != nullptr);
|
||||
return data.elements [index];
|
||||
}
|
||||
|
||||
/** Returns a pointer to the first object in the array.
|
||||
|
||||
This will return a null pointer if the array's empty.
|
||||
@see getLast
|
||||
*/
|
||||
inline ObjectClass* getFirst() const noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
return numUsed > 0 ? data.elements [0]
|
||||
: static_cast <ObjectClass*> (nullptr);
|
||||
}
|
||||
|
||||
/** Returns a pointer to the last object in the array.
|
||||
|
||||
This will return a null pointer if the array's empty.
|
||||
@see getFirst
|
||||
*/
|
||||
inline ObjectClass* getLast() const noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
return numUsed > 0 ? data.elements [numUsed - 1]
|
||||
: static_cast <ObjectClass*> (nullptr);
|
||||
}
|
||||
|
||||
/** Returns a pointer to the actual array data.
|
||||
This pointer will only be valid until the next time a non-const method
|
||||
is called on the array.
|
||||
*/
|
||||
inline ObjectClass** getRawDataPointer() noexcept
|
||||
{
|
||||
return data.elements;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a pointer to the first element in the array.
|
||||
This method is provided for compatibility with standard C++ iteration mechanisms.
|
||||
*/
|
||||
inline ObjectClass** begin() const noexcept
|
||||
{
|
||||
return data.elements;
|
||||
}
|
||||
|
||||
/** Returns a pointer to the element which follows the last element in the array.
|
||||
This method is provided for compatibility with standard C++ iteration mechanisms.
|
||||
*/
|
||||
inline ObjectClass** end() const noexcept
|
||||
{
|
||||
return data.elements + numUsed;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Finds the index of an object which might be in the array.
|
||||
|
||||
@param objectToLookFor the object to look for
|
||||
@returns the index at which the object was found, or -1 if it's not found
|
||||
*/
|
||||
int indexOf (const ObjectClass* const objectToLookFor) const noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
ObjectClass* const* e = data.elements.getData();
|
||||
ObjectClass* const* const end_ = e + numUsed;
|
||||
|
||||
for (; e != end_; ++e)
|
||||
if (objectToLookFor == *e)
|
||||
return static_cast <int> (e - data.elements.getData());
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Returns true if the array contains a specified object.
|
||||
|
||||
@param objectToLookFor the object to look for
|
||||
@returns true if the object is in the array
|
||||
*/
|
||||
bool contains (const ObjectClass* const objectToLookFor) const noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
ObjectClass* const* e = data.elements.getData();
|
||||
ObjectClass* const* const end_ = e + numUsed;
|
||||
|
||||
for (; e != end_; ++e)
|
||||
if (objectToLookFor == *e)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Appends a new object to the end of the array.
|
||||
|
||||
Note that the this object will be deleted by the OwnedArray when it
|
||||
is removed, so be careful not to delete it somewhere else.
|
||||
|
||||
Also be careful not to add the same object to the array more than once,
|
||||
as this will obviously cause deletion of dangling pointers.
|
||||
|
||||
@param newObject the new object to add to the array
|
||||
@see set, insert, addIfNotAlreadyThere, addSorted
|
||||
*/
|
||||
ObjectClass* add (ObjectClass* const newObject) noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
data.ensureAllocatedSize (numUsed + 1);
|
||||
bassert (data.elements != nullptr);
|
||||
data.elements [numUsed++] = const_cast <ObjectClass*> (newObject);
|
||||
return const_cast <ObjectClass*> (newObject);
|
||||
}
|
||||
|
||||
/** Inserts a new object into the array at the given index.
|
||||
|
||||
Note that the this object will be deleted by the OwnedArray when it
|
||||
is removed, so be careful not to delete it somewhere else.
|
||||
|
||||
If the index is less than 0 or greater than the size of the array, the
|
||||
element will be added to the end of the array.
|
||||
Otherwise, it will be inserted into the array, moving all the later elements
|
||||
along to make room.
|
||||
|
||||
Be careful not to add the same object to the array more than once,
|
||||
as this will obviously cause deletion of dangling pointers.
|
||||
|
||||
@param indexToInsertAt the index at which the new element should be inserted
|
||||
@param newObject the new object to add to the array
|
||||
@see add, addSorted, addIfNotAlreadyThere, set
|
||||
*/
|
||||
void insert (int indexToInsertAt,
|
||||
ObjectClass* const newObject) noexcept
|
||||
{
|
||||
if (indexToInsertAt >= 0)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (indexToInsertAt > numUsed)
|
||||
indexToInsertAt = numUsed;
|
||||
|
||||
data.ensureAllocatedSize (numUsed + 1);
|
||||
bassert (data.elements != nullptr);
|
||||
|
||||
ObjectClass** const e = data.elements + indexToInsertAt;
|
||||
const int numToMove = numUsed - indexToInsertAt;
|
||||
|
||||
if (numToMove > 0)
|
||||
memmove (e + 1, e, sizeof (ObjectClass*) * (size_t) numToMove);
|
||||
|
||||
*e = const_cast <ObjectClass*> (newObject);
|
||||
++numUsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
add (newObject);
|
||||
}
|
||||
}
|
||||
|
||||
/** Inserts an array of values into this array at a given position.
|
||||
|
||||
If the index is less than 0 or greater than the size of the array, the
|
||||
new elements will be added to the end of the array.
|
||||
Otherwise, they will be inserted into the array, moving all the later elements
|
||||
along to make room.
|
||||
|
||||
@param indexToInsertAt the index at which the first new element should be inserted
|
||||
@param newObjects the new values to add to the array
|
||||
@param numberOfElements how many items are in the array
|
||||
@see insert, add, addSorted, set
|
||||
*/
|
||||
void insertArray (int indexToInsertAt,
|
||||
ObjectClass* const* newObjects,
|
||||
int numberOfElements)
|
||||
{
|
||||
if (numberOfElements > 0)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
data.ensureAllocatedSize (numUsed + numberOfElements);
|
||||
ObjectClass** insertPos = data.elements;
|
||||
|
||||
if (isPositiveAndBelow (indexToInsertAt, numUsed))
|
||||
{
|
||||
insertPos += indexToInsertAt;
|
||||
const size_t numberToMove = (size_t) (numUsed - indexToInsertAt);
|
||||
memmove (insertPos + numberOfElements, insertPos, numberToMove * sizeof (ObjectClass*));
|
||||
}
|
||||
else
|
||||
{
|
||||
insertPos += numUsed;
|
||||
}
|
||||
|
||||
numUsed += numberOfElements;
|
||||
|
||||
while (--numberOfElements >= 0)
|
||||
*insertPos++ = *newObjects++;
|
||||
}
|
||||
}
|
||||
|
||||
/** Appends a new object at the end of the array as long as the array doesn't
|
||||
already contain it.
|
||||
|
||||
If the array already contains a matching object, nothing will be done.
|
||||
|
||||
@param newObject the new object to add to the array
|
||||
*/
|
||||
void addIfNotAlreadyThere (ObjectClass* const newObject) noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (! contains (newObject))
|
||||
add (newObject);
|
||||
}
|
||||
|
||||
/** Replaces an object in the array with a different one.
|
||||
|
||||
If the index is less than zero, this method does nothing.
|
||||
If the index is beyond the end of the array, the new object is added to the end of the array.
|
||||
|
||||
Be careful not to add the same object to the array more than once,
|
||||
as this will obviously cause deletion of dangling pointers.
|
||||
|
||||
@param indexToChange the index whose value you want to change
|
||||
@param newObject the new value to set for this index.
|
||||
@param deleteOldElement whether to delete the object that's being replaced with the new one
|
||||
@see add, insert, remove
|
||||
*/
|
||||
void set (const int indexToChange,
|
||||
const ObjectClass* const newObject,
|
||||
const bool deleteOldElement = true)
|
||||
{
|
||||
if (indexToChange >= 0)
|
||||
{
|
||||
ObjectClass* toDelete = nullptr;
|
||||
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (indexToChange < numUsed)
|
||||
{
|
||||
if (deleteOldElement)
|
||||
{
|
||||
toDelete = data.elements [indexToChange];
|
||||
|
||||
if (toDelete == newObject)
|
||||
toDelete = nullptr;
|
||||
}
|
||||
|
||||
data.elements [indexToChange] = const_cast <ObjectClass*> (newObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
data.ensureAllocatedSize (numUsed + 1);
|
||||
data.elements [numUsed++] = const_cast <ObjectClass*> (newObject);
|
||||
}
|
||||
}
|
||||
|
||||
// don't want to use a ScopedPointer here because if the
|
||||
// object has a private destructor, both OwnedArray and
|
||||
// ScopedPointer would need to be friend classes..
|
||||
ContainerDeletePolicy <ObjectClass>::destroy (toDelete);
|
||||
}
|
||||
else
|
||||
{
|
||||
bassertfalse; // you're trying to set an object at a negative index, which doesn't have
|
||||
// any effect - but since the object is not being added, it may be leaking..
|
||||
}
|
||||
}
|
||||
|
||||
/** Adds elements from another array to the end of this array.
|
||||
|
||||
@param arrayToAddFrom the array from which to copy the elements
|
||||
@param startIndex the first element of the other array to start copying from
|
||||
@param numElementsToAdd how many elements to add from the other array. If this
|
||||
value is negative or greater than the number of available elements,
|
||||
all available elements will be copied.
|
||||
@see add
|
||||
*/
|
||||
template <class OtherArrayType>
|
||||
void addArray (const OtherArrayType& arrayToAddFrom,
|
||||
int startIndex = 0,
|
||||
int numElementsToAdd = -1)
|
||||
{
|
||||
const typename OtherArrayType::ScopedLockType lock1 (arrayToAddFrom.getLock());
|
||||
const ScopedLockType lock2 (getLock());
|
||||
|
||||
if (startIndex < 0)
|
||||
{
|
||||
bassertfalse;
|
||||
startIndex = 0;
|
||||
}
|
||||
|
||||
if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size())
|
||||
numElementsToAdd = arrayToAddFrom.size() - startIndex;
|
||||
|
||||
data.ensureAllocatedSize (numUsed + numElementsToAdd);
|
||||
bassert (numElementsToAdd <= 0 || data.elements != nullptr);
|
||||
|
||||
while (--numElementsToAdd >= 0)
|
||||
{
|
||||
data.elements [numUsed] = arrayToAddFrom.getUnchecked (startIndex++);
|
||||
++numUsed;
|
||||
}
|
||||
}
|
||||
|
||||
/** Adds copies of the elements in another array to the end of this array.
|
||||
|
||||
The other array must be either an OwnedArray of a compatible type of object, or an Array
|
||||
containing pointers to the same kind of object. The objects involved must provide
|
||||
a copy constructor, and this will be used to create new copies of each element, and
|
||||
add them to this array.
|
||||
|
||||
@param arrayToAddFrom the array from which to copy the elements
|
||||
@param startIndex the first element of the other array to start copying from
|
||||
@param numElementsToAdd how many elements to add from the other array. If this
|
||||
value is negative or greater than the number of available elements,
|
||||
all available elements will be copied.
|
||||
@see add
|
||||
*/
|
||||
template <class OtherArrayType>
|
||||
void addCopiesOf (const OtherArrayType& arrayToAddFrom,
|
||||
int startIndex = 0,
|
||||
int numElementsToAdd = -1)
|
||||
{
|
||||
const typename OtherArrayType::ScopedLockType lock1 (arrayToAddFrom.getLock());
|
||||
const ScopedLockType lock2 (getLock());
|
||||
|
||||
if (startIndex < 0)
|
||||
{
|
||||
bassertfalse;
|
||||
startIndex = 0;
|
||||
}
|
||||
|
||||
if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size())
|
||||
numElementsToAdd = arrayToAddFrom.size() - startIndex;
|
||||
|
||||
data.ensureAllocatedSize (numUsed + numElementsToAdd);
|
||||
bassert (numElementsToAdd <= 0 || data.elements != nullptr);
|
||||
|
||||
while (--numElementsToAdd >= 0)
|
||||
{
|
||||
data.elements [numUsed] = new ObjectClass (*arrayToAddFrom.getUnchecked (startIndex++));
|
||||
++numUsed;
|
||||
}
|
||||
}
|
||||
|
||||
/** Inserts a new object into the array assuming that the array is sorted.
|
||||
|
||||
This will use a comparator to find the position at which the new object
|
||||
should go. If the array isn't sorted, the behaviour of this
|
||||
method will be unpredictable.
|
||||
|
||||
@param comparator the comparator to use to compare the elements - see the sort method
|
||||
for details about this object's structure
|
||||
@param newObject the new object to insert to the array
|
||||
@returns the index at which the new object was added
|
||||
@see add, sort, indexOfSorted
|
||||
*/
|
||||
template <class ElementComparator>
|
||||
int addSorted (ElementComparator& comparator, ObjectClass* const newObject) noexcept
|
||||
{
|
||||
(void) comparator; // if you pass in an object with a static compareElements() method, this
|
||||
// avoids getting warning messages about the parameter being unused
|
||||
const ScopedLockType lock (getLock());
|
||||
const int index = findInsertIndexInSortedArray (comparator, data.elements.getData(), newObject, 0, numUsed);
|
||||
insert (index, newObject);
|
||||
return index;
|
||||
}
|
||||
|
||||
/** Finds the index of an object in the array, assuming that the array is sorted.
|
||||
|
||||
This will use a comparator to do a binary-chop to find the index of the given
|
||||
element, if it exists. If the array isn't sorted, the behaviour of this
|
||||
method will be unpredictable.
|
||||
|
||||
@param comparator the comparator to use to compare the elements - see the sort()
|
||||
method for details about the form this object should take
|
||||
@param objectToLookFor the object to search for
|
||||
@returns the index of the element, or -1 if it's not found
|
||||
@see addSorted, sort
|
||||
*/
|
||||
template <typename ElementComparator>
|
||||
int indexOfSorted (ElementComparator& comparator, const ObjectClass* const objectToLookFor) const noexcept
|
||||
{
|
||||
(void) comparator;
|
||||
const ScopedLockType lock (getLock());
|
||||
int s = 0, e = numUsed;
|
||||
|
||||
while (s < e)
|
||||
{
|
||||
if (comparator.compareElements (objectToLookFor, data.elements [s]) == 0)
|
||||
return s;
|
||||
|
||||
const int halfway = (s + e) / 2;
|
||||
if (halfway == s)
|
||||
break;
|
||||
|
||||
if (comparator.compareElements (objectToLookFor, data.elements [halfway]) >= 0)
|
||||
s = halfway;
|
||||
else
|
||||
e = halfway;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Removes an object from the array.
|
||||
|
||||
This will remove the object at a given index (optionally also
|
||||
deleting it) and move back all the subsequent objects to close the gap.
|
||||
If the index passed in is out-of-range, nothing will happen.
|
||||
|
||||
@param indexToRemove the index of the element to remove
|
||||
@param deleteObject whether to delete the object that is removed
|
||||
@see removeObject, removeRange
|
||||
*/
|
||||
void remove (const int indexToRemove,
|
||||
const bool deleteObject = true)
|
||||
{
|
||||
ObjectClass* toDelete = nullptr;
|
||||
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (isPositiveAndBelow (indexToRemove, numUsed))
|
||||
{
|
||||
ObjectClass** const e = data.elements + indexToRemove;
|
||||
|
||||
if (deleteObject)
|
||||
toDelete = *e;
|
||||
|
||||
--numUsed;
|
||||
const int numToShift = numUsed - indexToRemove;
|
||||
|
||||
if (numToShift > 0)
|
||||
memmove (e, e + 1, sizeof (ObjectClass*) * (size_t) numToShift);
|
||||
}
|
||||
}
|
||||
|
||||
// don't want to use a ScopedPointer here because if the
|
||||
// object has a private destructor, both OwnedArray and
|
||||
// ScopedPointer would need to be friend classes..
|
||||
ContainerDeletePolicy <ObjectClass>::destroy (toDelete);
|
||||
|
||||
if ((numUsed << 1) < data.numAllocated)
|
||||
minimiseStorageOverheads();
|
||||
}
|
||||
|
||||
/** Removes and returns an object from the array without deleting it.
|
||||
|
||||
This will remove the object at a given index and return it, moving back all
|
||||
the subsequent objects to close the gap. If the index passed in is out-of-range,
|
||||
nothing will happen.
|
||||
|
||||
@param indexToRemove the index of the element to remove
|
||||
@see remove, removeObject, removeRange
|
||||
*/
|
||||
ObjectClass* removeAndReturn (const int indexToRemove)
|
||||
{
|
||||
ObjectClass* removedItem = nullptr;
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (isPositiveAndBelow (indexToRemove, numUsed))
|
||||
{
|
||||
ObjectClass** const e = data.elements + indexToRemove;
|
||||
removedItem = *e;
|
||||
|
||||
--numUsed;
|
||||
const int numToShift = numUsed - indexToRemove;
|
||||
|
||||
if (numToShift > 0)
|
||||
memmove (e, e + 1, sizeof (ObjectClass*) * (size_t) numToShift);
|
||||
|
||||
if ((numUsed << 1) < data.numAllocated)
|
||||
minimiseStorageOverheads();
|
||||
}
|
||||
|
||||
return removedItem;
|
||||
}
|
||||
|
||||
/** Removes a specified object from the array.
|
||||
|
||||
If the item isn't found, no action is taken.
|
||||
|
||||
@param objectToRemove the object to try to remove
|
||||
@param deleteObject whether to delete the object (if it's found)
|
||||
@see remove, removeRange
|
||||
*/
|
||||
void removeObject (const ObjectClass* const objectToRemove,
|
||||
const bool deleteObject = true)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
ObjectClass** const e = data.elements.getData();
|
||||
|
||||
for (int i = 0; i < numUsed; ++i)
|
||||
{
|
||||
if (objectToRemove == e[i])
|
||||
{
|
||||
remove (i, deleteObject);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes a range of objects from the array.
|
||||
|
||||
This will remove a set of objects, starting from the given index,
|
||||
and move any 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 object to remove
|
||||
@param numberToRemove how many objects should be removed
|
||||
@param deleteObjects whether to delete the objects that get removed
|
||||
@see remove, removeObject
|
||||
*/
|
||||
void removeRange (int startIndex,
|
||||
const int numberToRemove,
|
||||
const bool deleteObjects = true)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
const int endIndex = blimit (0, numUsed, startIndex + numberToRemove);
|
||||
startIndex = blimit (0, numUsed, startIndex);
|
||||
|
||||
if (endIndex > startIndex)
|
||||
{
|
||||
if (deleteObjects)
|
||||
{
|
||||
for (int i = startIndex; i < endIndex; ++i)
|
||||
{
|
||||
ContainerDeletePolicy <ObjectClass>::destroy (data.elements [i]);
|
||||
data.elements [i] = nullptr; // (in case one of the destructors accesses this array and hits a dangling pointer)
|
||||
}
|
||||
}
|
||||
|
||||
const int rangeSize = endIndex - startIndex;
|
||||
ObjectClass** e = data.elements + startIndex;
|
||||
int numToShift = numUsed - endIndex;
|
||||
numUsed -= rangeSize;
|
||||
|
||||
while (--numToShift >= 0)
|
||||
{
|
||||
*e = e [rangeSize];
|
||||
++e;
|
||||
}
|
||||
|
||||
if ((numUsed << 1) < data.numAllocated)
|
||||
minimiseStorageOverheads();
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes the last n objects from the array.
|
||||
|
||||
@param howManyToRemove how many objects to remove from the end of the array
|
||||
@param deleteObjects whether to also delete the objects that are removed
|
||||
@see remove, removeObject, removeRange
|
||||
*/
|
||||
void removeLast (int howManyToRemove = 1,
|
||||
const bool deleteObjects = true)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (howManyToRemove >= numUsed)
|
||||
clear (deleteObjects);
|
||||
else
|
||||
removeRange (numUsed - howManyToRemove, howManyToRemove, deleteObjects);
|
||||
}
|
||||
|
||||
/** Swaps a pair of objects in the array.
|
||||
|
||||
If either of the indexes passed in is out-of-range, nothing will happen,
|
||||
otherwise the two objects at these positions will be exchanged.
|
||||
*/
|
||||
void swap (const int index1,
|
||||
const int index2) noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (isPositiveAndBelow (index1, numUsed)
|
||||
&& isPositiveAndBelow (index2, numUsed))
|
||||
{
|
||||
std::swap (data.elements [index1],
|
||||
data.elements [index2]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Moves one of the objects to a different position.
|
||||
|
||||
This will move the object 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 object 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 object to end up. If this
|
||||
is less than zero, it will be moved to the end of the array
|
||||
*/
|
||||
void move (const int currentIndex,
|
||||
int newIndex) noexcept
|
||||
{
|
||||
if (currentIndex != newIndex)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
|
||||
if (isPositiveAndBelow (currentIndex, numUsed))
|
||||
{
|
||||
if (! isPositiveAndBelow (newIndex, numUsed))
|
||||
newIndex = numUsed - 1;
|
||||
|
||||
ObjectClass* const value = data.elements [currentIndex];
|
||||
|
||||
if (newIndex > currentIndex)
|
||||
{
|
||||
memmove (data.elements + currentIndex,
|
||||
data.elements + currentIndex + 1,
|
||||
sizeof (ObjectClass*) * (size_t) (newIndex - currentIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove (data.elements + newIndex + 1,
|
||||
data.elements + newIndex,
|
||||
sizeof (ObjectClass*) * (size_t) (currentIndex - newIndex));
|
||||
}
|
||||
|
||||
data.elements [newIndex] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** This swaps the contents of this array with those of another array.
|
||||
|
||||
If you need to exchange two arrays, this is vastly quicker than using copy-by-value
|
||||
because it just swaps their internal pointers.
|
||||
*/
|
||||
template <class OtherArrayType>
|
||||
void swapWith (OtherArrayType& otherArray) noexcept
|
||||
{
|
||||
const ScopedLockType lock1 (getLock());
|
||||
const typename OtherArrayType::ScopedLockType lock2 (otherArray.getLock());
|
||||
|
||||
data.swapWith (otherArray.data);
|
||||
std::swap (numUsed, otherArray.numUsed);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** 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() noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
data.shrinkToNoMoreThan (numUsed);
|
||||
}
|
||||
|
||||
/** 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 (const int minNumElements) noexcept
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
data.ensureAllocatedSize (minNumElements);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Sorts the elements in the array.
|
||||
|
||||
This will use a comparator object to sort the elements into order. The object
|
||||
passed must have a method of the form:
|
||||
@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 the comparator to use for comparing elements.
|
||||
@param retainOrderOfEquivalentItems if this is true, then items
|
||||
which the comparator says are equivalent will be
|
||||
kept in the order in which they currently appear
|
||||
in the array. This is slower to perform, but may
|
||||
be important in some cases. If it's false, a faster
|
||||
algorithm is used, but equivalent elements may be
|
||||
rearranged.
|
||||
@see sortArray, indexOfSorted
|
||||
*/
|
||||
template <class ElementComparator>
|
||||
void sort (ElementComparator& comparator,
|
||||
const bool retainOrderOfEquivalentItems = false) const noexcept
|
||||
{
|
||||
(void) comparator; // if you pass in an object with a static compareElements() method, this
|
||||
// avoids getting warning messages about the parameter being unused
|
||||
|
||||
const ScopedLockType lock (getLock());
|
||||
sortArray (comparator, data.elements.getData(), 0, size() - 1, retainOrderOfEquivalentItems);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the CriticalSection that locks this array.
|
||||
To lock, you can call getLock().enter() and getLock().exit(), or preferably use
|
||||
an object of ScopedLockType as an RAII lock for it.
|
||||
*/
|
||||
inline const TypeOfCriticalSectionToUse& getLock() const noexcept { return data; }
|
||||
|
||||
/** Returns the type of scoped lock to use for locking this array */
|
||||
typedef typename TypeOfCriticalSectionToUse::ScopedLockType ScopedLockType;
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
ArrayAllocationBase <ObjectClass*, TypeOfCriticalSectionToUse> data;
|
||||
int numUsed;
|
||||
|
||||
void deleteAllObjects()
|
||||
{
|
||||
while (numUsed > 0)
|
||||
ContainerDeletePolicy <ObjectClass>::destroy (data.elements [--numUsed]);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
|
||||
#endif
|
||||
@@ -91,6 +91,6 @@ private:
|
||||
const ValueType originalValue;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_SCOPEDVALUESETTER_H_INCLUDED
|
||||
|
||||
@@ -91,7 +91,7 @@ FatalError::FatalError (char const* message, char const* fileName, int lineNumbe
|
||||
|
||||
static LockType s_mutex;
|
||||
|
||||
LockType::ScopedLockType lock (s_mutex);
|
||||
std::lock_guard <LockType> lock (s_mutex);
|
||||
|
||||
String const backtraceString = SystemStats::getStackBacktrace ();
|
||||
|
||||
|
||||
@@ -149,6 +149,6 @@ private:
|
||||
static Reporter* s_reporter;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace beast
|
||||
template <typename Function>
|
||||
double measureFunctionCallTime (Function f)
|
||||
{
|
||||
int64 const startTime (Time::getHighResolutionTicks ());
|
||||
std::int64_t const startTime (Time::getHighResolutionTicks ());
|
||||
f ();
|
||||
return Time::highResolutionTicksToSeconds (
|
||||
Time::getHighResolutionTicks () - startTime);
|
||||
@@ -40,7 +40,7 @@ template <typename Function,
|
||||
typename P5, typename P6, typename P7, typename P8>
|
||||
double measureFunctionCallTime (Function f, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
|
||||
{
|
||||
int64 const startTime (Time::getHighResolutionTicks ());
|
||||
std::int64_t const startTime (Time::getHighResolutionTicks ());
|
||||
f (p1, p2, p3, p4, p5 ,p6 ,p7 ,p8);
|
||||
return Time::highResolutionTicksToSeconds (
|
||||
Time::getHighResolutionTicks () - startTime);
|
||||
@@ -51,7 +51,7 @@ template <typename Function,
|
||||
typename P5, typename P6, typename P7, typename P8>
|
||||
double measureFunctionCallTime (Function f, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
|
||||
{
|
||||
int64 const startTime (Time::getHighResolutionTicks ());
|
||||
std::int64_t const startTime (Time::getHighResolutionTicks ());
|
||||
f (p1, p2, p3, p4, p5 ,p6 ,p7 ,p8);
|
||||
return Time::highResolutionTicksToSeconds (
|
||||
Time::getHighResolutionTicks () - startTime);
|
||||
@@ -62,7 +62,7 @@ template <typename Function,
|
||||
typename P5, typename P6, typename P7, typename P8>
|
||||
double measureFunctionCallTime (Function f, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
|
||||
{
|
||||
int64 const startTime (Time::getHighResolutionTicks ());
|
||||
std::int64_t const startTime (Time::getHighResolutionTicks ());
|
||||
f (p1, p2, p3, p4, p5 ,p6 ,p7 ,p8);
|
||||
return Time::highResolutionTicksToSeconds (
|
||||
Time::getHighResolutionTicks () - startTime);
|
||||
@@ -73,13 +73,13 @@ template <typename Function,
|
||||
typename P5, typename P6, typename P7, typename P8>
|
||||
double measureFunctionCallTime (Function f, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
|
||||
{
|
||||
int64 const startTime (Time::getHighResolutionTicks ());
|
||||
std::int64_t const startTime (Time::getHighResolutionTicks ());
|
||||
f (p1, p2, p3, p4, p5 ,p6 ,p7 ,p8);
|
||||
return Time::highResolutionTicksToSeconds (
|
||||
Time::getHighResolutionTicks () - startTime);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace beast
|
||||
|
||||
http://semver.org/
|
||||
*/
|
||||
class BEAST_API SemanticVersion
|
||||
class SemanticVersion
|
||||
{
|
||||
public:
|
||||
int majorVersion;
|
||||
@@ -74,6 +74,6 @@ private:
|
||||
static bool chopIdentifiers (StringArray* value, bool preRelease, String& input);
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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_THROW_H_INCLUDED
|
||||
#define BEAST_THROW_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
/** Throw an exception, with a debugger hook.
|
||||
|
||||
This provides an opportunity to utilize the debugger before
|
||||
the stack is unwound.
|
||||
*/
|
||||
namespace Debug
|
||||
{
|
||||
extern void breakPoint ();
|
||||
};
|
||||
|
||||
template <class Exception>
|
||||
void Throw (Exception const& e, char const* = "", int = 0)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
|
||||
#endif
|
||||
@@ -36,7 +36,7 @@ void repeatableShuffle (int const numberOfItems, T& arrayOfItems, Random& r)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void repeatableShuffle (int const numberOfItems, T& arrayOfItems, int64 seedValue)
|
||||
void repeatableShuffle (int const numberOfItems, T& arrayOfItems, std::int64_t seedValue)
|
||||
{
|
||||
Random r (seedValue);
|
||||
repeatableShuffle (numberOfItems, arrayOfItems, r);
|
||||
@@ -64,7 +64,7 @@ struct Payload
|
||||
@param maximumBytes The largest number of bytes in the resulting payload.
|
||||
@param seedValue The value to seed the random number generator with.
|
||||
*/
|
||||
void repeatableRandomFill (int minimumBytes, int maximumBytes, int64 seedValue) noexcept
|
||||
void repeatableRandomFill (int minimumBytes, int maximumBytes, std::int64_t seedValue) noexcept
|
||||
{
|
||||
bassert (minimumBytes >=0 && maximumBytes <= bufferSize);
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ bool DirectoryIterator::next()
|
||||
return next (nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
bool DirectoryIterator::next (bool* const isDirResult, bool* const isHiddenResult, int64* const fileSize,
|
||||
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;
|
||||
@@ -156,4 +156,4 @@ float DirectoryIterator::getEstimatedProgress() const
|
||||
return detailedIndex / totalNumFiles;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace beast
|
||||
|
||||
It can also guess how far it's got using a wildly inaccurate algorithm.
|
||||
*/
|
||||
class BEAST_API DirectoryIterator : LeakChecked <DirectoryIterator>, public Uncopyable
|
||||
class DirectoryIterator : LeakChecked <DirectoryIterator>, public Uncopyable
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
*/
|
||||
bool next (bool* isDirectory,
|
||||
bool* isHidden,
|
||||
int64* fileSize,
|
||||
std::int64_t* fileSize,
|
||||
Time* modTime,
|
||||
Time* creationTime,
|
||||
bool* isReadOnly);
|
||||
@@ -122,7 +122,7 @@ private:
|
||||
~NativeIterator();
|
||||
|
||||
bool next (String& filenameFound,
|
||||
bool* isDirectory, bool* isHidden, int64* fileSize,
|
||||
bool* isDirectory, bool* isHidden, std::int64_t* fileSize,
|
||||
Time* modTime, Time* creationTime, bool* isReadOnly);
|
||||
|
||||
class Pimpl;
|
||||
@@ -146,6 +146,6 @@ private:
|
||||
File currentFile;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_DIRECTORYITERATOR_H_INCLUDED
|
||||
|
||||
@@ -354,7 +354,7 @@ bool File::isAChildOf (const File& potentialParent) const
|
||||
}
|
||||
|
||||
int File::hashCode() const { return fullPath.hashCode(); }
|
||||
int64 File::hashCode64() const { return fullPath.hashCode64(); }
|
||||
std::int64_t File::hashCode64() const { return fullPath.hashCode64(); }
|
||||
|
||||
//==============================================================================
|
||||
bool File::isAbsolutePath (const String& path)
|
||||
@@ -422,7 +422,7 @@ File File::getSiblingFile (const String& fileName) const
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
String File::descriptionOfSizeInBytes (const int64 bytes)
|
||||
String File::descriptionOfSizeInBytes (const std::int64_t bytes)
|
||||
{
|
||||
const char* suffix;
|
||||
double divisor = 0;
|
||||
@@ -477,9 +477,9 @@ Result File::createDirectory() const
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
Time File::getLastModificationTime() const { int64 m, a, c; getFileTimesInternal (m, a, c); return Time (m); }
|
||||
Time File::getLastAccessTime() const { int64 m, a, c; getFileTimesInternal (m, a, c); return Time (a); }
|
||||
Time File::getCreationTime() const { int64 m, a, c; getFileTimesInternal (m, a, c); return Time (c); }
|
||||
Time File::getLastModificationTime() const { std::int64_t m, a, c; getFileTimesInternal (m, a, c); return Time (m); }
|
||||
Time File::getLastAccessTime() const { std::int64_t m, a, c; getFileTimesInternal (m, a, c); return Time (a); }
|
||||
Time File::getCreationTime() const { std::int64_t m, a, c; getFileTimesInternal (m, a, c); return Time (c); }
|
||||
|
||||
bool File::setLastModificationTime (Time t) const { return setFileTimesInternal (t.toMilliseconds(), 0, 0); }
|
||||
bool File::setLastAccessTime (Time t) const { return setFileTimesInternal (0, t.toMilliseconds(), 0); }
|
||||
@@ -694,7 +694,7 @@ FileOutputStream* File::createOutputStream (const size_t bufferSize) const
|
||||
bool File::appendData (const void* const dataToAppend,
|
||||
const size_t numberOfBytes) const
|
||||
{
|
||||
bassert (((ssize_t) numberOfBytes) >= 0);
|
||||
bassert (((std::ptrdiff_t) numberOfBytes) >= 0);
|
||||
|
||||
if (numberOfBytes == 0)
|
||||
return true;
|
||||
|
||||
@@ -24,8 +24,17 @@
|
||||
#ifndef BEAST_FILE_H_INCLUDED
|
||||
#define BEAST_FILE_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
#include "../containers/Array.h"
|
||||
#include "../memory/MemoryBlock.h"
|
||||
#include "../misc/Result.h"
|
||||
#include "../time/Time.h"
|
||||
#include "../text/StringArray.h"
|
||||
#include "../threads/CriticalSection.h"
|
||||
|
||||
namespace beast {
|
||||
|
||||
class FileInputStream;
|
||||
class FileOutputStream;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
@@ -39,7 +48,7 @@ namespace beast
|
||||
|
||||
@see FileInputStream, FileOutputStream
|
||||
*/
|
||||
class BEAST_API File
|
||||
class File
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
@@ -123,14 +132,14 @@ public:
|
||||
|
||||
@returns the number of bytes in the file, or 0 if it doesn't exist.
|
||||
*/
|
||||
int64 getSize() const;
|
||||
std::int64_t getSize() const;
|
||||
|
||||
/** Utility function to convert a file size in bytes to a neat string description.
|
||||
|
||||
So for example 100 would return "100 bytes", 2000 would return "2 KB",
|
||||
2000000 would produce "2 MB", etc.
|
||||
*/
|
||||
static String descriptionOfSizeInBytes (int64 bytes);
|
||||
static String descriptionOfSizeInBytes (std::int64_t bytes);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the complete, absolute path of this file.
|
||||
@@ -235,7 +244,7 @@ public:
|
||||
This is based on the filename. Obviously it's possible, although unlikely, that
|
||||
two files will have the same hash-code.
|
||||
*/
|
||||
int64 hashCode64() const;
|
||||
std::int64_t hashCode64() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a file that represents a relative (or absolute) sub-path of the current one.
|
||||
@@ -698,14 +707,14 @@ public:
|
||||
@returns the number of bytes free, or 0 if there's a problem finding this out
|
||||
@see getVolumeTotalSize
|
||||
*/
|
||||
int64 getBytesFreeOnVolume() const;
|
||||
std::int64_t getBytesFreeOnVolume() const;
|
||||
|
||||
/** Returns the total size of the drive that contains this file.
|
||||
|
||||
@returns the total number of bytes that the volume can hold
|
||||
@see getBytesFreeOnVolume
|
||||
*/
|
||||
int64 getVolumeTotalSize() const;
|
||||
std::int64_t getVolumeTotalSize() const;
|
||||
|
||||
/** Returns true if this file is on a CD or DVD drive. */
|
||||
bool isOnCDRomDrive() const;
|
||||
@@ -842,7 +851,7 @@ public:
|
||||
|
||||
@see SpecialLocationType
|
||||
*/
|
||||
static File BEAST_CALLTYPE getSpecialLocation (const SpecialLocationType type);
|
||||
static File getSpecialLocation (const SpecialLocationType type);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a temporary file in the system's temp directory.
|
||||
@@ -946,12 +955,12 @@ private:
|
||||
Result createDirectoryInternal (const String&) const;
|
||||
bool copyInternal (const File&) const;
|
||||
bool moveInternal (const File&) const;
|
||||
bool setFileTimesInternal (int64 m, int64 a, int64 c) const;
|
||||
void getFileTimesInternal (int64& m, int64& a, int64& c) const;
|
||||
bool setFileTimesInternal (std::int64_t m, std::int64_t a, std::int64_t c) const;
|
||||
void getFileTimesInternal (std::int64_t& m, std::int64_t& a, std::int64_t& c) const;
|
||||
bool setFileReadOnlyInternal (bool) const;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
namespace beast
|
||||
{
|
||||
|
||||
int64 beast_fileSetPosition (void* handle, int64 pos);
|
||||
std::int64_t beast_fileSetPosition (void* handle, std::int64_t pos);
|
||||
|
||||
//==============================================================================
|
||||
FileInputStream::FileInputStream (const File& f)
|
||||
@@ -43,7 +43,7 @@ FileInputStream::~FileInputStream()
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int64 FileInputStream::getTotalLength()
|
||||
std::int64_t FileInputStream::getTotalLength()
|
||||
{
|
||||
return file.getSize();
|
||||
}
|
||||
@@ -72,18 +72,18 @@ bool FileInputStream::isExhausted()
|
||||
return currentPosition >= getTotalLength();
|
||||
}
|
||||
|
||||
int64 FileInputStream::getPosition()
|
||||
std::int64_t FileInputStream::getPosition()
|
||||
{
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
bool FileInputStream::setPosition (int64 pos)
|
||||
bool FileInputStream::setPosition (std::int64_t pos)
|
||||
{
|
||||
bassert (openedOk());
|
||||
|
||||
if (pos != currentPosition)
|
||||
{
|
||||
pos = blimit ((int64) 0, getTotalLength(), pos);
|
||||
pos = blimit ((std::int64_t) 0, getTotalLength(), pos);
|
||||
|
||||
needToSeek |= (currentPosition != pos);
|
||||
currentPosition = pos;
|
||||
@@ -92,4 +92,4 @@ bool FileInputStream::setPosition (int64 pos)
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace beast
|
||||
|
||||
@see InputStream, FileOutputStream, File::createInputStream
|
||||
*/
|
||||
class BEAST_API FileInputStream
|
||||
class FileInputStream
|
||||
: public InputStream
|
||||
, LeakChecked <FileInputStream>
|
||||
{
|
||||
@@ -71,17 +71,17 @@ public:
|
||||
|
||||
|
||||
//==============================================================================
|
||||
int64 getTotalLength();
|
||||
std::int64_t getTotalLength();
|
||||
int read (void* destBuffer, int maxBytesToRead);
|
||||
bool isExhausted();
|
||||
int64 getPosition();
|
||||
bool setPosition (int64 pos);
|
||||
std::int64_t getPosition();
|
||||
bool setPosition (std::int64_t pos);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
File file;
|
||||
void* fileHandle;
|
||||
int64 currentPosition;
|
||||
std::int64_t currentPosition;
|
||||
Result status;
|
||||
bool needToSeek;
|
||||
|
||||
@@ -90,6 +90,6 @@ private:
|
||||
size_t readInternal (void* buffer, size_t numBytes);
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_FILEINPUTSTREAM_H_INCLUDED
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
namespace beast
|
||||
{
|
||||
|
||||
int64 beast_fileSetPosition (void* handle, int64 pos);
|
||||
std::int64_t beast_fileSetPosition (void* handle, std::int64_t pos);
|
||||
|
||||
//==============================================================================
|
||||
FileOutputStream::FileOutputStream (const File& f, const size_t bufferSizeToUse)
|
||||
@@ -46,12 +46,12 @@ FileOutputStream::~FileOutputStream()
|
||||
closeHandle();
|
||||
}
|
||||
|
||||
int64 FileOutputStream::getPosition()
|
||||
std::int64_t FileOutputStream::getPosition()
|
||||
{
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
bool FileOutputStream::setPosition (int64 newPosition)
|
||||
bool FileOutputStream::setPosition (std::int64_t newPosition)
|
||||
{
|
||||
if (newPosition != currentPosition)
|
||||
{
|
||||
@@ -68,7 +68,7 @@ bool FileOutputStream::flushBuffer()
|
||||
|
||||
if (bytesInBuffer > 0)
|
||||
{
|
||||
ok = (writeInternal (buffer, bytesInBuffer) == (ssize_t) bytesInBuffer);
|
||||
ok = (writeInternal (buffer, bytesInBuffer) == (std::ptrdiff_t) bytesInBuffer);
|
||||
bytesInBuffer = 0;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ void FileOutputStream::flush()
|
||||
|
||||
bool FileOutputStream::write (const void* const src, const size_t numBytes)
|
||||
{
|
||||
bassert (src != nullptr && ((ssize_t) numBytes) >= 0);
|
||||
bassert (src != nullptr && ((std::ptrdiff_t) numBytes) >= 0);
|
||||
|
||||
if (bytesInBuffer + numBytes < bufferSize)
|
||||
{
|
||||
@@ -104,22 +104,22 @@ bool FileOutputStream::write (const void* const src, const size_t numBytes)
|
||||
}
|
||||
else
|
||||
{
|
||||
const ssize_t bytesWritten = writeInternal (src, numBytes);
|
||||
const std::ptrdiff_t bytesWritten = writeInternal (src, numBytes);
|
||||
|
||||
if (bytesWritten < 0)
|
||||
return false;
|
||||
|
||||
currentPosition += bytesWritten;
|
||||
return bytesWritten == (ssize_t) numBytes;
|
||||
return bytesWritten == (std::ptrdiff_t) numBytes;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileOutputStream::writeRepeatedByte (uint8 byte, size_t numBytes)
|
||||
bool FileOutputStream::writeRepeatedByte (std::uint8_t byte, size_t numBytes)
|
||||
{
|
||||
bassert (((ssize_t) numBytes) >= 0);
|
||||
bassert (((std::ptrdiff_t) numBytes) >= 0);
|
||||
|
||||
if (bytesInBuffer + numBytes < bufferSize)
|
||||
{
|
||||
@@ -132,4 +132,4 @@ bool FileOutputStream::writeRepeatedByte (uint8 byte, size_t numBytes)
|
||||
return OutputStream::writeRepeatedByte (byte, numBytes);
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace beast
|
||||
|
||||
@see OutputStream, FileInputStream, File::createOutputStream
|
||||
*/
|
||||
class BEAST_API FileOutputStream
|
||||
class FileOutputStream
|
||||
: public OutputStream
|
||||
, LeakChecked <FileOutputStream>
|
||||
{
|
||||
@@ -87,10 +87,10 @@ public:
|
||||
|
||||
//==============================================================================
|
||||
void flush() override;
|
||||
int64 getPosition() override;
|
||||
bool setPosition (int64) override;
|
||||
std::int64_t getPosition() override;
|
||||
bool setPosition (std::int64_t) override;
|
||||
bool write (const void*, size_t) override;
|
||||
bool writeRepeatedByte (uint8 byte, size_t numTimesToRepeat) override;
|
||||
bool writeRepeatedByte (std::uint8_t byte, size_t numTimesToRepeat) override;
|
||||
|
||||
|
||||
private:
|
||||
@@ -98,7 +98,7 @@ private:
|
||||
File file;
|
||||
void* fileHandle;
|
||||
Result status;
|
||||
int64 currentPosition;
|
||||
std::int64_t currentPosition;
|
||||
size_t bufferSize, bytesInBuffer;
|
||||
HeapBlock <char> buffer;
|
||||
|
||||
@@ -106,10 +106,10 @@ private:
|
||||
void closeHandle();
|
||||
void flushInternal();
|
||||
bool flushBuffer();
|
||||
int64 setPositionInternal (int64);
|
||||
ssize_t writeInternal (const void*, size_t);
|
||||
std::int64_t setPositionInternal (std::int64_t);
|
||||
std::ptrdiff_t writeInternal (const void*, size_t);
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -168,4 +168,4 @@ bool FileSearchPath::isFileInPath (const File& fileToCheck,
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace beast
|
||||
|
||||
@see File
|
||||
*/
|
||||
class BEAST_API FileSearchPath : LeakChecked <FileSearchPath>
|
||||
class FileSearchPath : LeakChecked <FileSearchPath>
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
@@ -158,6 +158,6 @@ private:
|
||||
void init (const String& path);
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_FILESEARCHPATH_H_INCLUDED
|
||||
|
||||
@@ -68,7 +68,7 @@ Result RandomAccessFile::read (void* buffer, ByteCount numBytes, ByteCount* pAct
|
||||
|
||||
Result RandomAccessFile::write (const void* data, ByteCount numBytes, ByteCount* pActualAmount)
|
||||
{
|
||||
bassert (data != nullptr && ((ssize_t) numBytes) >= 0);
|
||||
bassert (data != nullptr && ((std::ptrdiff_t) numBytes) >= 0);
|
||||
|
||||
Result result (Result::ok ());
|
||||
|
||||
@@ -128,7 +128,7 @@ public:
|
||||
static void createRecords (HeapBlock <Record>& records,
|
||||
int numRecords,
|
||||
int maxBytes,
|
||||
int64 seedValue)
|
||||
std::int64_t seedValue)
|
||||
{
|
||||
using namespace UnitTestUtilities;
|
||||
|
||||
@@ -157,7 +157,7 @@ public:
|
||||
void writeRecords (RandomAccessFile& file,
|
||||
int numRecords,
|
||||
HeapBlock <Record> const& records,
|
||||
int64 seedValue)
|
||||
std::int64_t seedValue)
|
||||
{
|
||||
using namespace UnitTestUtilities;
|
||||
|
||||
@@ -181,7 +181,7 @@ public:
|
||||
void readRecords (RandomAccessFile& file,
|
||||
int numRecords,
|
||||
HeapBlock <Record> const& records,
|
||||
int64 seedValue)
|
||||
std::int64_t seedValue)
|
||||
{
|
||||
using namespace UnitTestUtilities;
|
||||
|
||||
|
||||
@@ -39,14 +39,14 @@ namespace beast
|
||||
|
||||
@see FileInputStream, FileOutputStream
|
||||
*/
|
||||
class BEAST_API RandomAccessFile : public Uncopyable, LeakChecked <RandomAccessFile>
|
||||
class RandomAccessFile : public Uncopyable, LeakChecked <RandomAccessFile>
|
||||
{
|
||||
public:
|
||||
/** The type of an FileOffset.
|
||||
|
||||
This can be useful when writing templates.
|
||||
*/
|
||||
typedef int64 FileOffset;
|
||||
typedef std::int64_t FileOffset;
|
||||
|
||||
/** The type of a byte count.
|
||||
|
||||
@@ -194,7 +194,7 @@ private:
|
||||
FileOffset currentPosition;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -114,4 +114,4 @@ bool TemporaryFile::deleteTemporaryFile() const
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace beast
|
||||
|
||||
@see File, FileOutputStream
|
||||
*/
|
||||
class BEAST_API TemporaryFile : LeakChecked <TemporaryFile>, public Uncopyable
|
||||
class TemporaryFile : LeakChecked <TemporaryFile>, public Uncopyable
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
@@ -161,6 +161,6 @@ private:
|
||||
const File temporaryFile, targetFile;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_TEMPORARYFILE_H_INCLUDED
|
||||
|
||||
@@ -60,4 +60,4 @@ void logAssertion (const char* const filename, const int lineNum)
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace beast
|
||||
The logger class also contains methods for writing messages to the debugger's
|
||||
output stream.
|
||||
*/
|
||||
class BEAST_API Logger
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
the caller must make sure that it is not deleted while still being used.
|
||||
A null pointer can be passed-in to disable any logging.
|
||||
*/
|
||||
static void BEAST_CALLTYPE setCurrentLogger (Logger* newLogger) noexcept;
|
||||
static void setCurrentLogger (Logger* newLogger) noexcept;
|
||||
|
||||
/** Returns the current logger, or nullptr if none has been set. */
|
||||
static Logger* getCurrentLogger() noexcept;
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
|
||||
@see logMessage
|
||||
*/
|
||||
static void BEAST_CALLTYPE writeToLog (const String& message);
|
||||
static void writeToLog (const String& message);
|
||||
|
||||
|
||||
//==============================================================================
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
This can be called directly, or by using the DBG() macro in
|
||||
CompilerConfig.h (which will avoid calling the method in non-debug builds).
|
||||
*/
|
||||
static void BEAST_CALLTYPE outputDebugString (const String& text);
|
||||
static void outputDebugString (const String& text);
|
||||
|
||||
|
||||
protected:
|
||||
@@ -88,6 +88,6 @@ private:
|
||||
static Logger* currentLogger;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_LOGGER_H_INCLUDED
|
||||
|
||||
@@ -84,6 +84,6 @@ inline T radiansToDegrees (U radians)
|
||||
return deg;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
Random::Random (const int64 seedValue) noexcept
|
||||
Random::Random (const std::int64_t seedValue) noexcept
|
||||
: seed (seedValue)
|
||||
{
|
||||
nextInt (); // fixes a bug where the first int is always 0
|
||||
@@ -41,23 +41,23 @@ Random::~Random() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
void Random::setSeed (const int64 newSeed) noexcept
|
||||
void Random::setSeed (const std::int64_t newSeed) noexcept
|
||||
{
|
||||
seed = newSeed;
|
||||
|
||||
nextInt (); // fixes a bug where the first int is always 0
|
||||
}
|
||||
|
||||
void Random::combineSeed (const int64 seedValue) noexcept
|
||||
void Random::combineSeed (const std::int64_t seedValue) noexcept
|
||||
{
|
||||
seed ^= nextInt64() ^ seedValue;
|
||||
}
|
||||
|
||||
void Random::setSeedRandomly()
|
||||
{
|
||||
static int64 globalSeed = 0;
|
||||
static std::int64_t globalSeed = 0;
|
||||
|
||||
combineSeed (globalSeed ^ (int64) (pointer_sized_int) this);
|
||||
combineSeed (globalSeed ^ (std::int64_t) (std::intptr_t) this);
|
||||
combineSeed (Time::getMillisecondCounter());
|
||||
combineSeed (Time::getHighResolutionTicks());
|
||||
combineSeed (Time::getHighResolutionTicksPerSecond());
|
||||
@@ -76,7 +76,7 @@ Random& Random::getSystemRandom() noexcept
|
||||
//==============================================================================
|
||||
int Random::nextInt() noexcept
|
||||
{
|
||||
seed = (seed * literal64bit (0x5deece66d) + 11) & literal64bit (0xffffffffffff);
|
||||
seed = (seed * 0x5deece66dLL + 11) & 0xffffffffffffULL;
|
||||
|
||||
return (int) (seed >> 16);
|
||||
}
|
||||
@@ -84,12 +84,12 @@ int Random::nextInt() noexcept
|
||||
int Random::nextInt (const int maxValue) noexcept
|
||||
{
|
||||
bassert (maxValue > 0);
|
||||
return (int) ((((unsigned int) nextInt()) * (uint64) maxValue) >> 32);
|
||||
return (int) ((((unsigned int) nextInt()) * (std::uint64_t) maxValue) >> 32);
|
||||
}
|
||||
|
||||
int64 Random::nextInt64() noexcept
|
||||
std::int64_t Random::nextInt64() noexcept
|
||||
{
|
||||
return (((int64) nextInt()) << 32) | (int64) (uint64) (uint32) nextInt();
|
||||
return (((std::int64_t) nextInt()) << 32) | (std::int64_t) (std::uint64_t) (std::uint32_t) nextInt();
|
||||
}
|
||||
|
||||
bool Random::nextBool() noexcept
|
||||
@@ -99,12 +99,12 @@ bool Random::nextBool() noexcept
|
||||
|
||||
float Random::nextFloat() noexcept
|
||||
{
|
||||
return static_cast <uint32> (nextInt()) / (float) 0xffffffff;
|
||||
return static_cast <std::uint32_t> (nextInt()) / (float) 0xffffffff;
|
||||
}
|
||||
|
||||
double Random::nextDouble() noexcept
|
||||
{
|
||||
return static_cast <uint32> (nextInt()) / (double) 0xffffffff;
|
||||
return static_cast <std::uint32_t> (nextInt()) / (double) 0xffffffff;
|
||||
}
|
||||
|
||||
void Random::fillBitsRandomly (void* const buffer, size_t bytes)
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
|
||||
new Random (Time::currentTimeMillis())
|
||||
*/
|
||||
explicit Random (int64 seedValue) noexcept;
|
||||
explicit Random (std::int64_t seedValue) noexcept;
|
||||
|
||||
/** Creates a Random object using a random seed value.
|
||||
Internally, this calls setSeedRandomly() to randomise the seed.
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
|
||||
@returns a random integer from the full range 0x8000000000000000 to 0x7fffffffffffffff
|
||||
*/
|
||||
int64 nextInt64() noexcept;
|
||||
std::int64_t nextInt64() noexcept;
|
||||
|
||||
/** Returns the next random floating-point number.
|
||||
|
||||
@@ -94,13 +94,13 @@ public:
|
||||
|
||||
//==============================================================================
|
||||
/** Resets this Random object to a given seed value. */
|
||||
void setSeed (int64 newSeed) noexcept;
|
||||
void setSeed (std::int64_t newSeed) noexcept;
|
||||
|
||||
/** Merges this object's seed with another value.
|
||||
This sets the seed to be a value created by combining the current seed and this
|
||||
new value.
|
||||
*/
|
||||
void combineSeed (int64 seedValue) noexcept;
|
||||
void combineSeed (std::int64_t seedValue) noexcept;
|
||||
|
||||
/** Reseeds this generator using a value generated from various semi-random system
|
||||
properties like the current time, etc.
|
||||
@@ -120,9 +120,9 @@ public:
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
int64 seed;
|
||||
std::int64_t seed;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_RANDOM_H_INCLUDED
|
||||
|
||||
@@ -258,6 +258,6 @@ private:
|
||||
ValueType start, end;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_RANGE_H_INCLUDED
|
||||
|
||||
@@ -56,7 +56,7 @@ MemoryBlock::MemoryBlock (const MemoryBlock& other)
|
||||
MemoryBlock::MemoryBlock (const void* const dataToInitialiseFrom, const size_t sizeInBytes)
|
||||
: size (sizeInBytes)
|
||||
{
|
||||
bassert (((ssize_t) sizeInBytes) >= 0);
|
||||
bassert (((std::ptrdiff_t) sizeInBytes) >= 0);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
@@ -160,7 +160,7 @@ void MemoryBlock::swapWith (MemoryBlock& other) noexcept
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void MemoryBlock::fillWith (const uint8 value) noexcept
|
||||
void MemoryBlock::fillWith (const std::uint8_t value) noexcept
|
||||
{
|
||||
memset (data, (int) value, size);
|
||||
}
|
||||
@@ -295,16 +295,16 @@ void MemoryBlock::setBitRange (const size_t bitRangeStart, size_t numBits, int b
|
||||
{
|
||||
size_t byte = bitRangeStart >> 3;
|
||||
size_t offsetInByte = bitRangeStart & 7;
|
||||
uint32 mask = ~((((uint32) 0xffffffff) << (32 - numBits)) >> (32 - numBits));
|
||||
std::uint32_t mask = ~((((std::uint32_t) 0xffffffff) << (32 - numBits)) >> (32 - numBits));
|
||||
|
||||
while (numBits > 0 && (size_t) byte < size)
|
||||
{
|
||||
const size_t bitsThisTime = bmin (numBits, 8 - offsetInByte);
|
||||
|
||||
const uint32 tempMask = (mask << offsetInByte) | ~((((uint32) 0xffffffff) >> offsetInByte) << offsetInByte);
|
||||
const uint32 tempBits = (uint32) bitsToSet << 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) (((uint32) data[byte] & tempMask) | tempBits);
|
||||
data[byte] = (char) (((std::uint32_t) data[byte] & tempMask) | tempBits);
|
||||
|
||||
++byte;
|
||||
numBits -= bitsThisTime;
|
||||
@@ -366,7 +366,7 @@ String MemoryBlock::toBase64Encoding() const
|
||||
d.write ('.');
|
||||
|
||||
for (size_t i = 0; i < numChars; ++i)
|
||||
d.write ((beast_wchar) (uint8) base64EncodingTable [getBitRange (i * 6, 6)]);
|
||||
d.write ((beast_wchar) (std::uint8_t) base64EncodingTable [getBitRange (i * 6, 6)]);
|
||||
|
||||
d.writeNull();
|
||||
return destString;
|
||||
@@ -407,4 +407,4 @@ bool MemoryBlock::fromBase64Encoding (const String& s)
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -24,15 +24,16 @@
|
||||
#ifndef BEAST_MEMORYBLOCK_H_INCLUDED
|
||||
#define BEAST_MEMORYBLOCK_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
#include "../../../beast/utility/LeakChecked.h"
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A class to hold a resizable block of raw data.
|
||||
|
||||
*/
|
||||
class BEAST_API MemoryBlock : LeakChecked <MemoryBlock>
|
||||
class MemoryBlock : LeakChecked <MemoryBlock>
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
@@ -160,7 +161,7 @@ public:
|
||||
|
||||
This is handy for clearing a block of memory to zero.
|
||||
*/
|
||||
void fillWith (uint8 valueToUse) noexcept;
|
||||
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.
|
||||
@@ -267,7 +268,7 @@ private:
|
||||
size_t size;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
#ifndef BEAST_SHAREDSINGLETON_H_INCLUDED
|
||||
#define BEAST_SHAREDSINGLETON_H_INCLUDED
|
||||
|
||||
#include "../../../beast/threads/SpinLock.h"
|
||||
#include "../../../beast/smart_ptr/SharedPtr.h"
|
||||
#include "../time/AtExitHook.h"
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
@@ -38,7 +42,7 @@ namespace beast
|
||||
@ingroup beast_core
|
||||
*/
|
||||
/** @{ */
|
||||
class BEAST_API SingletonLifetime
|
||||
class SingletonLifetime
|
||||
{
|
||||
public:
|
||||
// It would be nice if we didn't have to qualify the enumeration but
|
||||
@@ -88,7 +92,7 @@ public:
|
||||
SharedSingleton* instance = staticData.instance;
|
||||
if (instance == nullptr)
|
||||
{
|
||||
LockType::ScopedLockType lock (staticData.mutex);
|
||||
std::lock_guard <LockType> lock (staticData.mutex);
|
||||
instance = staticData.instance;
|
||||
if (instance == nullptr)
|
||||
{
|
||||
@@ -138,7 +142,7 @@ private:
|
||||
//
|
||||
{
|
||||
StaticData& staticData (getStaticData ());
|
||||
LockType::ScopedLockType lock (staticData.mutex);
|
||||
std::lock_guard <LockType> lock (staticData.mutex);
|
||||
|
||||
if (this->getReferenceCount() != 0)
|
||||
{
|
||||
@@ -180,7 +184,7 @@ private:
|
||||
|
||||
static StaticData& getStaticData ()
|
||||
{
|
||||
static uint8 storage [sizeof (StaticData)];
|
||||
static std::uint8_t storage [sizeof (StaticData)];
|
||||
return *(reinterpret_cast <StaticData*> (&storage [0]));
|
||||
}
|
||||
|
||||
@@ -193,6 +197,6 @@ private:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -80,4 +80,4 @@ Result::operator bool() const noexcept { return errorMessage.isEmpty(); }
|
||||
bool Result::failed() const noexcept { return errorMessage.isNotEmpty(); }
|
||||
bool Result::operator!() const noexcept { return errorMessage.isNotEmpty(); }
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace beast
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
class BEAST_API Result
|
||||
class Result
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
@@ -116,7 +116,7 @@ private:
|
||||
operator void*() const;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
e.g. "HKEY_CURRENT_USER\Software\foo\bar"
|
||||
@returns a DWORD indicating the type of the key.
|
||||
*/
|
||||
static uint32 getBinaryValue (const String& regValuePath, MemoryBlock& resultData);
|
||||
static std::uint32_t getBinaryValue (const String& regValuePath, MemoryBlock& resultData);
|
||||
|
||||
/** Sets a registry value as a string.
|
||||
This will take care of creating any groups needed to get to the given registry value.
|
||||
@@ -66,12 +66,12 @@ public:
|
||||
/** Sets a registry value as a DWORD.
|
||||
This will take care of creating any groups needed to get to the given registry value.
|
||||
*/
|
||||
static bool setValue (const String& regValuePath, uint32 value);
|
||||
static bool setValue (const String& regValuePath, std::uint32_t value);
|
||||
|
||||
/** Sets a registry value as a QWORD.
|
||||
This will take care of creating any groups needed to get to the given registry value.
|
||||
*/
|
||||
static bool setValue (const String& regValuePath, uint64 value);
|
||||
static bool setValue (const String& regValuePath, std::uint64_t value);
|
||||
|
||||
/** Sets a registry value as a binary block.
|
||||
This will take care of creating any groups needed to get to the given registry value.
|
||||
@@ -119,6 +119,6 @@ private:
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_WINDOWSREGISTRY_H_INCLUDED
|
||||
|
||||
@@ -261,7 +261,7 @@ public:
|
||||
}
|
||||
|
||||
bool next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, int64* const fileSize,
|
||||
bool* const isDir, bool* const isHidden, std::int64_t* const fileSize,
|
||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
|
||||
{
|
||||
if (dir != nullptr)
|
||||
@@ -310,7 +310,7 @@ DirectoryIterator::NativeIterator::~NativeIterator()
|
||||
}
|
||||
|
||||
bool DirectoryIterator::NativeIterator::next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, int64* const fileSize,
|
||||
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);
|
||||
@@ -371,4 +371,4 @@ void File::revealToUser() const
|
||||
getParentDirectory().startAsProcess();
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -1,37 +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
|
||||
{
|
||||
|
||||
bool Process::openEmailWithAttachments (const String& /* targetEmailAddress */,
|
||||
const String& /* emailSubject */,
|
||||
const String& /* bodyText */,
|
||||
const StringArray& /* filesToAttach */)
|
||||
{
|
||||
bassertfalse; // xxx todo
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
@@ -318,7 +318,7 @@ void CPUInformation::initialise() noexcept
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
uint32 beast_millisecondsSinceStartup() noexcept
|
||||
std::uint32_t beast_millisecondsSinceStartup() noexcept
|
||||
{
|
||||
timespec t;
|
||||
clock_gettime (CLOCK_MONOTONIC, &t);
|
||||
@@ -326,15 +326,15 @@ uint32 beast_millisecondsSinceStartup() noexcept
|
||||
return t.tv_sec * 1000 + t.tv_nsec / 1000000;
|
||||
}
|
||||
|
||||
int64 Time::getHighResolutionTicks() noexcept
|
||||
std::int64_t Time::getHighResolutionTicks() noexcept
|
||||
{
|
||||
timespec t;
|
||||
clock_gettime (CLOCK_MONOTONIC, &t);
|
||||
|
||||
return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / 1000);
|
||||
return (t.tv_sec * (std::int64_t) 1000000) + (t.tv_nsec / 1000);
|
||||
}
|
||||
|
||||
int64 Time::getHighResolutionTicksPerSecond() noexcept
|
||||
std::int64_t Time::getHighResolutionTicksPerSecond() noexcept
|
||||
{
|
||||
return 1000000; // (microseconds)
|
||||
}
|
||||
@@ -353,4 +353,4 @@ bool Time::setSystemTimeToThisTime() const
|
||||
return settimeofday (&t, 0) == 0;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -57,7 +57,7 @@ bool beast_isRunningUnderDebugger()
|
||||
return false;
|
||||
}
|
||||
|
||||
BEAST_API bool BEAST_CALLTYPE Process::isRunningUnderDebugger()
|
||||
bool Process::isRunningUnderDebugger()
|
||||
{
|
||||
return beast_isRunningUnderDebugger();
|
||||
}
|
||||
@@ -71,4 +71,4 @@ static void swapUserAndEffectiveUser()
|
||||
void Process::raisePrivilege() { if (geteuid() != 0 && getuid() == 0) swapUserAndEffectiveUser(); }
|
||||
void Process::lowerPrivilege() { if (geteuid() == 0 && getuid() != 0) swapUserAndEffectiveUser(); }
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -261,7 +261,7 @@ public:
|
||||
}
|
||||
|
||||
bool next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, int64* const fileSize,
|
||||
bool* const isDir, bool* const isHidden, std::int64_t* const fileSize,
|
||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
|
||||
{
|
||||
if (dir != nullptr)
|
||||
@@ -310,7 +310,7 @@ DirectoryIterator::NativeIterator::~NativeIterator()
|
||||
}
|
||||
|
||||
bool DirectoryIterator::NativeIterator::next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, int64* const fileSize,
|
||||
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);
|
||||
@@ -371,4 +371,4 @@ void File::revealToUser() const
|
||||
getParentDirectory().startAsProcess();
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -1,37 +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
|
||||
{
|
||||
|
||||
bool Process::openEmailWithAttachments (const String& /* targetEmailAddress */,
|
||||
const String& /* emailSubject */,
|
||||
const String& /* bodyText */,
|
||||
const StringArray& /* filesToAttach */)
|
||||
{
|
||||
bassertfalse; // xxx todo
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
@@ -143,7 +143,7 @@ void CPUInformation::initialise() noexcept
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
uint32 beast_millisecondsSinceStartup() noexcept
|
||||
std::uint32_t beast_millisecondsSinceStartup() noexcept
|
||||
{
|
||||
timespec t;
|
||||
clock_gettime (CLOCK_MONOTONIC, &t);
|
||||
@@ -151,15 +151,15 @@ uint32 beast_millisecondsSinceStartup() noexcept
|
||||
return t.tv_sec * 1000 + t.tv_nsec / 1000000;
|
||||
}
|
||||
|
||||
int64 Time::getHighResolutionTicks() noexcept
|
||||
std::int64_t Time::getHighResolutionTicks() noexcept
|
||||
{
|
||||
timespec t;
|
||||
clock_gettime (CLOCK_MONOTONIC, &t);
|
||||
|
||||
return (t.tv_sec * (int64) 1000000) + (t.tv_nsec / 1000);
|
||||
return (t.tv_sec * (std::int64_t) 1000000) + (t.tv_nsec / 1000);
|
||||
}
|
||||
|
||||
int64 Time::getHighResolutionTicksPerSecond() noexcept
|
||||
std::int64_t Time::getHighResolutionTicksPerSecond() noexcept
|
||||
{
|
||||
return 1000000; // (microseconds)
|
||||
}
|
||||
@@ -178,4 +178,4 @@ bool Time::setSystemTimeToThisTime() const
|
||||
return settimeofday (&t, 0) == 0;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -68,7 +68,7 @@ bool beast_isRunningUnderDebugger()
|
||||
return testResult < 0;
|
||||
}
|
||||
|
||||
BEAST_API bool BEAST_CALLTYPE Process::isRunningUnderDebugger()
|
||||
bool Process::isRunningUnderDebugger()
|
||||
{
|
||||
return beast_isRunningUnderDebugger();
|
||||
}
|
||||
@@ -82,4 +82,4 @@ static void swapUserAndEffectiveUser()
|
||||
void Process::raisePrivilege() { if (geteuid() != 0 && getuid() == 0) swapUserAndEffectiveUser(); }
|
||||
void Process::lowerPrivilege() { if (geteuid() == 0 && getuid() != 0) swapUserAndEffectiveUser(); }
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -332,7 +332,7 @@ public:
|
||||
}
|
||||
|
||||
bool next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, int64* const fileSize,
|
||||
bool* const isDir, bool* const isHidden, std::int64_t* const fileSize,
|
||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
|
||||
{
|
||||
BEAST_AUTORELEASEPOOL
|
||||
@@ -380,7 +380,7 @@ DirectoryIterator::NativeIterator::~NativeIterator()
|
||||
}
|
||||
|
||||
bool DirectoryIterator::NativeIterator::next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, int64* const fileSize,
|
||||
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);
|
||||
@@ -481,4 +481,4 @@ void File::addToDock() const
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -1,75 +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
|
||||
{
|
||||
|
||||
bool Process::openEmailWithAttachments (const String& targetEmailAddress,
|
||||
const String& emailSubject,
|
||||
const String& bodyText,
|
||||
const StringArray& filesToAttach)
|
||||
{
|
||||
#if BEAST_IOS
|
||||
//xxx probably need to use MFMailComposeViewController
|
||||
bassertfalse;
|
||||
return false;
|
||||
#else
|
||||
BEAST_AUTORELEASEPOOL
|
||||
{
|
||||
String script;
|
||||
script << "tell application \"Mail\"\r\n"
|
||||
"set newMessage to make new outgoing message with properties {subject:\""
|
||||
<< emailSubject.replace ("\"", "\\\"")
|
||||
<< "\", content:\""
|
||||
<< bodyText.replace ("\"", "\\\"")
|
||||
<< "\" & return & return}\r\n"
|
||||
"tell newMessage\r\n"
|
||||
"set visible to true\r\n"
|
||||
"set sender to \"sdfsdfsdfewf\"\r\n"
|
||||
"make new to recipient at end of to recipients with properties {address:\""
|
||||
<< targetEmailAddress
|
||||
<< "\"}\r\n";
|
||||
|
||||
for (int i = 0; i < filesToAttach.size(); ++i)
|
||||
{
|
||||
script << "tell content\r\n"
|
||||
"make new attachment with properties {file name:\""
|
||||
<< filesToAttach[i].replace ("\"", "\\\"")
|
||||
<< "\"} at after the last paragraph\r\n"
|
||||
"end tell\r\n";
|
||||
}
|
||||
|
||||
script << "end tell\r\n"
|
||||
"end tell\r\n";
|
||||
|
||||
NSAppleScript* s = [[NSAppleScript alloc] initWithSource: beastStringToNS (script)];
|
||||
NSDictionary* error = nil;
|
||||
const bool ok = [s executeAndReturnError: &error] != nil;
|
||||
[s release];
|
||||
|
||||
return ok;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
@@ -93,4 +93,4 @@ String String::convertToPrecomposedUnicode() const
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -48,9 +48,9 @@ void Logger::outputDebugString (const String& text)
|
||||
namespace SystemStatsHelpers
|
||||
{
|
||||
#if BEAST_INTEL && ! BEAST_NO_INLINE_ASM
|
||||
static void doCPUID (uint32& a, uint32& b, uint32& c, uint32& d, uint32 type)
|
||||
static void doCPUID (std::uint32_t& a, std::uint32_t& b, std::uint32_t& c, std::uint32_t& d, std::uint32_t type)
|
||||
{
|
||||
uint32 la = a, lb = b, lc = c, ld = d;
|
||||
std::uint32_t la = a, lb = b, lc = c, ld = d;
|
||||
|
||||
asm ("mov %%ebx, %%esi \n\t"
|
||||
"cpuid \n\t"
|
||||
@@ -70,7 +70,7 @@ namespace SystemStatsHelpers
|
||||
void CPUInformation::initialise() noexcept
|
||||
{
|
||||
#if BEAST_INTEL && ! BEAST_NO_INLINE_ASM
|
||||
uint32 a = 0, b = 0, d = 0, c = 0;
|
||||
std::uint32_t a = 0, b = 0, d = 0, c = 0;
|
||||
SystemStatsHelpers::doCPUID (a, b, c, d, 1);
|
||||
|
||||
hasMMX = (d & (1u << 23)) != 0;
|
||||
@@ -154,7 +154,7 @@ bool SystemStats::isOperatingSystem64Bit()
|
||||
|
||||
int SystemStats::getMemorySizeInMegabytes()
|
||||
{
|
||||
uint64 mem = 0;
|
||||
std::uint64_t mem = 0;
|
||||
size_t memSize = sizeof (mem);
|
||||
int mib[] = { CTL_HW, HW_MEMSIZE };
|
||||
sysctl (mib, 2, &mem, &memSize, 0, 0);
|
||||
@@ -164,8 +164,8 @@ int SystemStats::getMemorySizeInMegabytes()
|
||||
String SystemStats::getCpuVendor()
|
||||
{
|
||||
#if BEAST_INTEL && ! BEAST_NO_INLINE_ASM
|
||||
uint32 dummy = 0;
|
||||
uint32 vendor[4] = { 0 };
|
||||
std::uint32_t dummy = 0;
|
||||
std::uint32_t vendor[4] = { 0 };
|
||||
|
||||
SystemStatsHelpers::doCPUID (dummy, vendor[0], vendor[2], vendor[1], 0);
|
||||
|
||||
@@ -177,7 +177,7 @@ String SystemStats::getCpuVendor()
|
||||
|
||||
int SystemStats::getCpuSpeedInMegaherz()
|
||||
{
|
||||
uint64 speedHz = 0;
|
||||
std::uint64_t speedHz = 0;
|
||||
size_t speedSize = sizeof (speedHz);
|
||||
int mib[] = { CTL_HW, HW_CPU_FREQ };
|
||||
sysctl (mib, 2, &speedHz, &speedSize, 0, 0);
|
||||
@@ -246,16 +246,16 @@ public:
|
||||
else
|
||||
{
|
||||
numerator = timebase.numer;
|
||||
denominator = timebase.denom * (uint64) 1000000;
|
||||
denominator = timebase.denom * (std::uint64_t) 1000000;
|
||||
}
|
||||
|
||||
highResTimerFrequency = (timebase.denom * (uint64) 1000000000) / timebase.numer;
|
||||
highResTimerFrequency = (timebase.denom * (std::uint64_t) 1000000000) / timebase.numer;
|
||||
highResTimerToMillisecRatio = numerator / (double) denominator;
|
||||
}
|
||||
|
||||
inline uint32 millisecondsSinceStartup() const noexcept
|
||||
inline std::uint32_t millisecondsSinceStartup() const noexcept
|
||||
{
|
||||
return (uint32) ((mach_absolute_time() * numerator) / denominator);
|
||||
return (std::uint32_t) ((mach_absolute_time() * numerator) / denominator);
|
||||
}
|
||||
|
||||
inline double getMillisecondCounterHiRes() const noexcept
|
||||
@@ -263,10 +263,10 @@ public:
|
||||
return mach_absolute_time() * highResTimerToMillisecRatio;
|
||||
}
|
||||
|
||||
int64 highResTimerFrequency;
|
||||
std::int64_t highResTimerFrequency;
|
||||
|
||||
private:
|
||||
uint64 numerator, denominator;
|
||||
std::uint64_t numerator, denominator;
|
||||
double highResTimerToMillisecRatio;
|
||||
};
|
||||
|
||||
@@ -276,10 +276,10 @@ static HiResCounterHandler& hiResCounterHandler()
|
||||
return hiResCounterHandler;
|
||||
}
|
||||
|
||||
uint32 beast_millisecondsSinceStartup() noexcept { return hiResCounterHandler().millisecondsSinceStartup(); }
|
||||
std::uint32_t beast_millisecondsSinceStartup() noexcept { return hiResCounterHandler().millisecondsSinceStartup(); }
|
||||
double Time::getMillisecondCounterHiRes() noexcept { return hiResCounterHandler().getMillisecondCounterHiRes(); }
|
||||
int64 Time::getHighResolutionTicksPerSecond() noexcept { return hiResCounterHandler().highResTimerFrequency; }
|
||||
int64 Time::getHighResolutionTicks() noexcept { return (int64) mach_absolute_time(); }
|
||||
std::int64_t Time::getHighResolutionTicksPerSecond() noexcept { return hiResCounterHandler().highResTimerFrequency; }
|
||||
std::int64_t Time::getHighResolutionTicks() noexcept { return (std::int64_t) mach_absolute_time(); }
|
||||
|
||||
bool Time::setSystemTimeToThisTime() const
|
||||
{
|
||||
@@ -293,4 +293,4 @@ int SystemStats::getPageSize()
|
||||
return (int) NSPageSize();
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -78,9 +78,9 @@ bool beast_isRunningUnderDebugger()
|
||||
return testResult > 0;
|
||||
}
|
||||
|
||||
BEAST_API bool BEAST_CALLTYPE Process::isRunningUnderDebugger()
|
||||
bool Process::isRunningUnderDebugger()
|
||||
{
|
||||
return beast_isRunningUnderDebugger();
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -149,6 +149,6 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_OSX_OBJCHELPERS_H_INCLUDED
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace
|
||||
return statfs (f.getFullPathName().toUTF8(), &result) == 0;
|
||||
}
|
||||
|
||||
void updateStatInfoForFile (const String& path, bool* const isDir, int64* const fileSize,
|
||||
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)
|
||||
@@ -138,8 +138,8 @@ namespace
|
||||
|
||||
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 ? (int64) info.st_mtime * 1000 : 0);
|
||||
if (creationTime != nullptr) *creationTime = Time (statOk ? (int64) info.st_ctime * 1000 : 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)
|
||||
@@ -156,8 +156,8 @@ namespace
|
||||
return value == -1 ? getResultForErrno() : Result::ok();
|
||||
}
|
||||
|
||||
int getFD (void* handle) noexcept { return (int) (pointer_sized_int) handle; }
|
||||
void* fdToVoidPointer (int fd) noexcept { return (void*) (pointer_sized_int) fd; }
|
||||
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
|
||||
@@ -179,7 +179,7 @@ bool File::existsAsFile() const
|
||||
return exists() && ! isDirectory();
|
||||
}
|
||||
|
||||
int64 File::getSize() const
|
||||
std::int64_t File::getSize() const
|
||||
{
|
||||
beast_statStruct info;
|
||||
return beast_stat (fullPath, info) ? info.st_size : 0;
|
||||
@@ -214,7 +214,7 @@ bool File::setFileReadOnlyInternal (const bool shouldBeReadOnly) const
|
||||
return chmod (fullPath.toUTF8(), info.st_mode) == 0;
|
||||
}
|
||||
|
||||
void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int64& creationTime) const
|
||||
void File::getFileTimesInternal (std::int64_t& modificationTime, std::int64_t& accessTime, std::int64_t& creationTime) const
|
||||
{
|
||||
modificationTime = 0;
|
||||
accessTime = 0;
|
||||
@@ -223,13 +223,13 @@ void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int
|
||||
beast_statStruct info;
|
||||
if (beast_stat (fullPath, info))
|
||||
{
|
||||
modificationTime = (int64) info.st_mtime * 1000;
|
||||
accessTime = (int64) info.st_atime * 1000;
|
||||
creationTime = (int64) info.st_ctime * 1000;
|
||||
modificationTime = (std::int64_t) info.st_mtime * 1000;
|
||||
accessTime = (std::int64_t) info.st_atime * 1000;
|
||||
creationTime = (std::int64_t) info.st_ctime * 1000;
|
||||
}
|
||||
}
|
||||
|
||||
bool File::setFileTimesInternal (int64 modificationTime, int64 accessTime, int64 /*creationTime*/) const
|
||||
bool File::setFileTimesInternal (std::int64_t modificationTime, std::int64_t accessTime, std::int64_t /*creationTime*/) const
|
||||
{
|
||||
beast_statStruct info;
|
||||
|
||||
@@ -278,7 +278,7 @@ Result File::createDirectoryInternal (const String& fileName) const
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
int64 beast_fileSetPosition (void* handle, int64 pos)
|
||||
std::int64_t beast_fileSetPosition (void* handle, std::int64_t pos)
|
||||
{
|
||||
if (handle != 0 && lseek (getFD (handle), pos, SEEK_SET) == pos)
|
||||
return pos;
|
||||
@@ -307,7 +307,7 @@ void FileInputStream::closeHandle()
|
||||
|
||||
size_t FileInputStream::readInternal (void* const buffer, const size_t numBytes)
|
||||
{
|
||||
ssize_t result = 0;
|
||||
std::ptrdiff_t result = 0;
|
||||
|
||||
if (fileHandle != 0)
|
||||
{
|
||||
@@ -369,9 +369,9 @@ void FileOutputStream::closeHandle()
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t FileOutputStream::writeInternal (const void* const data, const size_t numBytes)
|
||||
std::ptrdiff_t FileOutputStream::writeInternal (const void* const data, const size_t numBytes)
|
||||
{
|
||||
ssize_t result = 0;
|
||||
std::ptrdiff_t result = 0;
|
||||
|
||||
if (fileHandle != 0)
|
||||
{
|
||||
@@ -512,7 +512,7 @@ Result RandomAccessFile::nativeRead (void* buffer, ByteCount numBytes, ByteCount
|
||||
{
|
||||
bassert (isOpen ());
|
||||
|
||||
ssize_t bytesRead = ::read (getFD (fileHandle), buffer, numBytes);
|
||||
std::ptrdiff_t bytesRead = ::read (getFD (fileHandle), buffer, numBytes);
|
||||
|
||||
if (bytesRead < 0)
|
||||
{
|
||||
@@ -537,7 +537,7 @@ Result RandomAccessFile::nativeWrite (void const* data, ByteCount numBytes, size
|
||||
{
|
||||
bassert (isOpen ());
|
||||
|
||||
ssize_t bytesWritten = ::write (getFD (fileHandle), data, numBytes);
|
||||
std::ptrdiff_t bytesWritten = ::write (getFD (fileHandle), data, numBytes);
|
||||
|
||||
// write(3) says that the actual return will be exactly -1 on
|
||||
// error, but we will assume anything negative indicates failure.
|
||||
@@ -627,20 +627,20 @@ File beast_getExecutableFile()
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int64 File::getBytesFreeOnVolume() const
|
||||
std::int64_t File::getBytesFreeOnVolume() const
|
||||
{
|
||||
struct statfs buf;
|
||||
if (beast_doStatFS (*this, buf))
|
||||
return (int64) buf.f_bsize * (int64) buf.f_bavail; // Note: this returns space available to non-super user
|
||||
return (std::int64_t) buf.f_bsize * (std::int64_t) buf.f_bavail; // Note: this returns space available to non-super user
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64 File::getVolumeTotalSize() const
|
||||
std::int64_t File::getVolumeTotalSize() const
|
||||
{
|
||||
struct statfs buf;
|
||||
if (beast_doStatFS (*this, buf))
|
||||
return (int64) buf.f_bsize * (int64) buf.f_blocks;
|
||||
return (std::int64_t) buf.f_bsize * (std::int64_t) buf.f_blocks;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -723,149 +723,6 @@ String beast_getOutputFromCommand (const String& command)
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
#if BEAST_IOS
|
||||
class InterProcessLock::Pimpl
|
||||
{
|
||||
public:
|
||||
Pimpl (const String&, int)
|
||||
: handle (1), refCount (1) // On iOS just fake success..
|
||||
{
|
||||
}
|
||||
|
||||
int handle, refCount;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class InterProcessLock::Pimpl
|
||||
{
|
||||
public:
|
||||
Pimpl (const String& lockName, const int timeOutMillisecs)
|
||||
: handle (0), refCount (1)
|
||||
{
|
||||
#if BEAST_MAC
|
||||
if (! createLockFile (File ("~/Library/Caches/com.beast.locks").getChildFile (lockName), timeOutMillisecs))
|
||||
// Fallback if the user's home folder is on a network drive with no ability to lock..
|
||||
createLockFile (File ("/tmp/com.beast.locks").getChildFile (lockName), timeOutMillisecs);
|
||||
|
||||
#else
|
||||
File tempFolder ("/var/tmp");
|
||||
if (! tempFolder.isDirectory())
|
||||
tempFolder = "/tmp";
|
||||
|
||||
createLockFile (tempFolder.getChildFile (lockName), timeOutMillisecs);
|
||||
#endif
|
||||
}
|
||||
|
||||
~Pimpl()
|
||||
{
|
||||
closeFile();
|
||||
}
|
||||
|
||||
bool createLockFile (const File& file, const int timeOutMillisecs)
|
||||
{
|
||||
file.create();
|
||||
handle = open (file.getFullPathName().toUTF8(), O_RDWR);
|
||||
|
||||
if (handle != 0)
|
||||
{
|
||||
struct flock fl;
|
||||
zerostruct (fl);
|
||||
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_type = F_WRLCK;
|
||||
|
||||
const int64 endTime = Time::currentTimeMillis() + timeOutMillisecs;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const int result = fcntl (handle, F_SETLK, &fl);
|
||||
|
||||
if (result >= 0)
|
||||
return true;
|
||||
|
||||
const int error = errno;
|
||||
|
||||
if (error != EINTR)
|
||||
{
|
||||
if (error == EBADF || error == ENOTSUP)
|
||||
return false;
|
||||
|
||||
if (timeOutMillisecs == 0
|
||||
|| (timeOutMillisecs > 0 && Time::currentTimeMillis() >= endTime))
|
||||
break;
|
||||
|
||||
Thread::sleep (10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closeFile();
|
||||
return true; // only false if there's a file system error. Failure to lock still returns true.
|
||||
}
|
||||
|
||||
void closeFile()
|
||||
{
|
||||
if (handle != 0)
|
||||
{
|
||||
struct flock fl;
|
||||
zerostruct (fl);
|
||||
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_type = F_UNLCK;
|
||||
|
||||
while (! (fcntl (handle, F_SETLKW, &fl) >= 0 || errno != EINTR))
|
||||
{}
|
||||
|
||||
close (handle);
|
||||
handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int handle, refCount;
|
||||
};
|
||||
#endif
|
||||
|
||||
InterProcessLock::InterProcessLock (const String& nm) : name (nm)
|
||||
{
|
||||
}
|
||||
|
||||
InterProcessLock::~InterProcessLock()
|
||||
{
|
||||
}
|
||||
|
||||
bool InterProcessLock::enter (const int timeOutMillisecs)
|
||||
{
|
||||
const ScopedLock sl (lock);
|
||||
|
||||
if (pimpl == nullptr)
|
||||
{
|
||||
pimpl = new Pimpl (name, timeOutMillisecs);
|
||||
|
||||
if (pimpl->handle == 0)
|
||||
pimpl = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
pimpl->refCount++;
|
||||
}
|
||||
|
||||
return pimpl != nullptr;
|
||||
}
|
||||
|
||||
void InterProcessLock::exit()
|
||||
{
|
||||
const ScopedLock sl (lock);
|
||||
|
||||
// Trying to release the lock too many times!
|
||||
bassert (pimpl != nullptr);
|
||||
|
||||
if (pimpl != nullptr && --(pimpl->refCount) == 0)
|
||||
pimpl = nullptr;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
bool DynamicLibrary::open (const String& name)
|
||||
@@ -889,284 +746,4 @@ void* DynamicLibrary::getFunction (const String& functionName) noexcept
|
||||
return handle != nullptr ? dlsym (handle, functionName.toUTF8()) : nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class ChildProcess::ActiveProcess : LeakChecked <ActiveProcess>, public Uncopyable
|
||||
{
|
||||
public:
|
||||
ActiveProcess (const StringArray& arguments)
|
||||
: childPID (0), pipeHandle (0), readHandle (0)
|
||||
{
|
||||
int pipeHandles[2] = { 0 };
|
||||
|
||||
if (pipe (pipeHandles) == 0)
|
||||
{
|
||||
const pid_t result = fork();
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
close (pipeHandles[0]);
|
||||
close (pipeHandles[1]);
|
||||
}
|
||||
else if (result == 0)
|
||||
{
|
||||
// we're the child process..
|
||||
close (pipeHandles[0]); // close the read handle
|
||||
dup2 (pipeHandles[1], 1); // turns the pipe into stdout
|
||||
dup2 (pipeHandles[1], 2); // + stderr
|
||||
close (pipeHandles[1]);
|
||||
|
||||
Array<char*> argv;
|
||||
for (int i = 0; i < arguments.size(); ++i)
|
||||
if (arguments[i].isNotEmpty())
|
||||
argv.add (arguments[i].toUTF8().getAddress());
|
||||
|
||||
argv.add (nullptr);
|
||||
|
||||
execvp (argv[0], argv.getRawDataPointer());
|
||||
exit (-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we're the parent process..
|
||||
childPID = result;
|
||||
pipeHandle = pipeHandles[0];
|
||||
close (pipeHandles[1]); // close the write handle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~ActiveProcess()
|
||||
{
|
||||
if (readHandle != 0)
|
||||
fclose (readHandle);
|
||||
|
||||
if (pipeHandle != 0)
|
||||
close (pipeHandle);
|
||||
}
|
||||
|
||||
bool isRunning() const
|
||||
{
|
||||
if (childPID != 0)
|
||||
{
|
||||
int childState;
|
||||
const int pid = waitpid (childPID, &childState, WNOHANG);
|
||||
return pid == 0 || ! (WIFEXITED (childState) || WIFSIGNALED (childState));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int read (void* const dest, const int numBytes)
|
||||
{
|
||||
bassert (dest != nullptr);
|
||||
|
||||
#ifdef fdopen
|
||||
#error // the zlib headers define this function as NULL!
|
||||
#endif
|
||||
|
||||
if (readHandle == 0 && childPID != 0)
|
||||
readHandle = fdopen (pipeHandle, "r");
|
||||
|
||||
if (readHandle != 0)
|
||||
return (int) fread (dest, 1, (size_t) numBytes, readHandle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool killProcess() const
|
||||
{
|
||||
return ::kill (childPID, SIGKILL) == 0;
|
||||
}
|
||||
|
||||
int childPID;
|
||||
|
||||
private:
|
||||
int pipeHandle;
|
||||
FILE* readHandle;
|
||||
};
|
||||
|
||||
bool ChildProcess::start (const String& command)
|
||||
{
|
||||
return start (StringArray::fromTokens (command, true));
|
||||
}
|
||||
|
||||
bool ChildProcess::start (const StringArray& args)
|
||||
{
|
||||
if (args.size() == 0)
|
||||
return false;
|
||||
|
||||
activeProcess = new ActiveProcess (args);
|
||||
|
||||
if (activeProcess->childPID == 0)
|
||||
activeProcess = nullptr;
|
||||
|
||||
return activeProcess != nullptr;
|
||||
}
|
||||
|
||||
bool ChildProcess::isRunning() const
|
||||
{
|
||||
return activeProcess != nullptr && activeProcess->isRunning();
|
||||
}
|
||||
|
||||
int ChildProcess::readProcessOutput (void* dest, int numBytes)
|
||||
{
|
||||
return activeProcess != nullptr ? activeProcess->read (dest, numBytes) : 0;
|
||||
}
|
||||
|
||||
bool ChildProcess::kill()
|
||||
{
|
||||
return activeProcess == nullptr || activeProcess->killProcess();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct HighResolutionTimer::Pimpl : public Uncopyable
|
||||
{
|
||||
Pimpl (HighResolutionTimer& t) : owner (t), thread (0), shouldStop (false)
|
||||
{
|
||||
}
|
||||
|
||||
~Pimpl()
|
||||
{
|
||||
bassert (thread == 0);
|
||||
}
|
||||
|
||||
void start (int newPeriod)
|
||||
{
|
||||
periodMs = newPeriod;
|
||||
|
||||
if (thread == 0)
|
||||
{
|
||||
shouldStop = false;
|
||||
|
||||
if (pthread_create (&thread, nullptr, timerThread, this) == 0)
|
||||
setThreadToRealtime (thread, (uint64) newPeriod);
|
||||
else
|
||||
bassertfalse;
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
if (thread != 0)
|
||||
{
|
||||
shouldStop = true;
|
||||
|
||||
while (thread != 0 && thread != pthread_self())
|
||||
Thread::yield();
|
||||
}
|
||||
}
|
||||
|
||||
HighResolutionTimer& owner;
|
||||
int volatile periodMs;
|
||||
|
||||
private:
|
||||
pthread_t thread;
|
||||
bool volatile shouldStop;
|
||||
|
||||
static void* timerThread (void* param)
|
||||
{
|
||||
#if ! BEAST_ANDROID
|
||||
int dummy;
|
||||
pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, &dummy);
|
||||
#endif
|
||||
|
||||
reinterpret_cast<Pimpl*> (param)->timerThread();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void timerThread()
|
||||
{
|
||||
Clock clock (periodMs);
|
||||
|
||||
while (! shouldStop)
|
||||
{
|
||||
clock.wait();
|
||||
owner.hiResTimerCallback();
|
||||
}
|
||||
|
||||
periodMs = 0;
|
||||
thread = 0;
|
||||
}
|
||||
|
||||
struct Clock
|
||||
{
|
||||
#if BEAST_MAC || BEAST_IOS
|
||||
Clock (double millis) noexcept
|
||||
{
|
||||
mach_timebase_info_data_t timebase;
|
||||
(void) mach_timebase_info (&timebase);
|
||||
delta = (((uint64_t) (millis * 1000000.0)) * timebase.numer) / timebase.denom;
|
||||
time = mach_absolute_time();
|
||||
}
|
||||
|
||||
void wait() noexcept
|
||||
{
|
||||
time += delta;
|
||||
mach_wait_until (time);
|
||||
}
|
||||
|
||||
uint64_t time, delta;
|
||||
|
||||
#elif BEAST_ANDROID || BEAST_BSD
|
||||
Clock (double millis) noexcept : delta ((uint64) (millis * 1000000))
|
||||
{
|
||||
}
|
||||
|
||||
void wait() noexcept
|
||||
{
|
||||
struct timespec t;
|
||||
t.tv_sec = (time_t) (delta / 1000000000);
|
||||
t.tv_nsec = (long) (delta % 1000000000);
|
||||
nanosleep (&t, nullptr);
|
||||
}
|
||||
|
||||
uint64 delta;
|
||||
#else
|
||||
Clock (double millis) noexcept : delta ((uint64) (millis * 1000000))
|
||||
{
|
||||
struct timespec t;
|
||||
clock_gettime (CLOCK_MONOTONIC, &t);
|
||||
time = 1000000000 * (int64) t.tv_sec + t.tv_nsec;
|
||||
}
|
||||
|
||||
void wait() noexcept
|
||||
{
|
||||
time += delta;
|
||||
|
||||
struct timespec t;
|
||||
t.tv_sec = (time_t) (time / 1000000000);
|
||||
t.tv_nsec = (long) (time % 1000000000);
|
||||
clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &t, nullptr);
|
||||
}
|
||||
|
||||
uint64 time, delta;
|
||||
#endif
|
||||
};
|
||||
|
||||
static bool setThreadToRealtime (pthread_t thread, uint64 periodMs)
|
||||
{
|
||||
#if BEAST_MAC || BEAST_IOS
|
||||
thread_time_constraint_policy_data_t policy;
|
||||
policy.period = (uint32_t) (periodMs * 1000000);
|
||||
policy.computation = 50000;
|
||||
policy.constraint = policy.period;
|
||||
policy.preemptible = true;
|
||||
|
||||
return thread_policy_set (pthread_mach_thread_np (thread),
|
||||
THREAD_TIME_CONSTRAINT_POLICY,
|
||||
(thread_policy_t) &policy,
|
||||
THREAD_TIME_CONSTRAINT_POLICY_COUNT) == KERN_SUCCESS;
|
||||
|
||||
#else
|
||||
(void) periodMs;
|
||||
struct sched_param param;
|
||||
param.sched_priority = sched_get_priority_max (SCHED_RR);
|
||||
return pthread_setschedparam (thread, SCHED_RR, ¶m) == 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -45,8 +45,8 @@ inline GUID uuidFromString (const char* const s) noexcept
|
||||
(s, "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
||||
&p0, &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10);
|
||||
|
||||
GUID g = { p0, (uint16) p1, (uint16) p2, { (uint8) p3, (uint8) p4, (uint8) p5, (uint8) p6,
|
||||
(uint8) p7, (uint8) p8, (uint8) p9, (uint8) p10 }};
|
||||
GUID g = { p0, (std::uint16_t) p1, (std::uint16_t) p2, { (std::uint8_t) p3, (std::uint8_t) p4, (std::uint8_t) p5, (std::uint8_t) p6,
|
||||
(std::uint8_t) p7, (std::uint8_t) p8, (std::uint8_t) p9, (std::uint8_t) p10 }};
|
||||
return g;
|
||||
}
|
||||
|
||||
@@ -165,6 +165,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_WIN32_COMSMARTPTR_H_INCLUDED
|
||||
|
||||
@@ -36,19 +36,19 @@ namespace WindowsFileHelpers
|
||||
return GetFileAttributes (path.toWideCharPointer());
|
||||
}
|
||||
|
||||
int64 fileTimeToTime (const FILETIME* const ft)
|
||||
std::int64_t fileTimeToTime (const FILETIME* const ft)
|
||||
{
|
||||
static_bassert (sizeof (ULARGE_INTEGER) == sizeof (FILETIME)); // tell me if this fails!
|
||||
|
||||
return (int64) ((reinterpret_cast<const ULARGE_INTEGER*> (ft)->QuadPart - literal64bit (116444736000000000)) / 10000);
|
||||
return (std::int64_t) ((reinterpret_cast<const ULARGE_INTEGER*> (ft)->QuadPart - 116444736000000000LL) / 10000);
|
||||
}
|
||||
|
||||
FILETIME* timeToFileTime (const int64 time, FILETIME* const ft) noexcept
|
||||
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 + literal64bit (116444736000000000));
|
||||
reinterpret_cast<ULARGE_INTEGER*> (ft)->QuadPart = (ULONGLONG) (time * 10000 + 116444736000000000LL);
|
||||
return ft;
|
||||
}
|
||||
|
||||
@@ -68,13 +68,13 @@ namespace WindowsFileHelpers
|
||||
return path;
|
||||
}
|
||||
|
||||
int64 getDiskSpaceInfo (const String& path, const bool total)
|
||||
std::int64_t getDiskSpaceInfo (const String& path, const bool total)
|
||||
{
|
||||
ULARGE_INTEGER spc, tot, totFree;
|
||||
|
||||
if (GetDiskFreeSpaceEx (getDriveFromPath (path).toWideCharPointer(), &spc, &tot, &totFree))
|
||||
return total ? (int64) tot.QuadPart
|
||||
: (int64) spc.QuadPart;
|
||||
return total ? (std::int64_t) tot.QuadPart
|
||||
: (std::int64_t) spc.QuadPart;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ Result File::createDirectoryInternal (const String& fileName) const
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int64 beast_fileSetPosition (void* handle, int64 pos)
|
||||
std::int64_t beast_fileSetPosition (void* handle, std::int64_t pos)
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = pos;
|
||||
@@ -279,7 +279,7 @@ void FileOutputStream::closeHandle()
|
||||
CloseHandle ((HANDLE) fileHandle);
|
||||
}
|
||||
|
||||
ssize_t FileOutputStream::writeInternal (const void* buffer, size_t numBytes)
|
||||
std::ptrdiff_t FileOutputStream::writeInternal (const void* buffer, size_t numBytes)
|
||||
{
|
||||
if (fileHandle != nullptr)
|
||||
{
|
||||
@@ -287,7 +287,7 @@ ssize_t FileOutputStream::writeInternal (const void* buffer, size_t numBytes)
|
||||
if (! WriteFile ((HANDLE) fileHandle, buffer, (DWORD) numBytes, &actualNum, 0))
|
||||
status = WindowsFileHelpers::getResultForLastError();
|
||||
|
||||
return (ssize_t) actualNum;
|
||||
return (std::ptrdiff_t) actualNum;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -468,17 +468,17 @@ Result RandomAccessFile::nativeFlush ()
|
||||
|
||||
//==============================================================================
|
||||
|
||||
int64 File::getSize() const
|
||||
std::int64_t File::getSize() const
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA attributes;
|
||||
|
||||
if (GetFileAttributesEx (fullPath.toWideCharPointer(), GetFileExInfoStandard, &attributes))
|
||||
return (((int64) attributes.nFileSizeHigh) << 32) | attributes.nFileSizeLow;
|
||||
return (((std::int64_t) attributes.nFileSizeHigh) << 32) | attributes.nFileSizeLow;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int64& creationTime) const
|
||||
void File::getFileTimesInternal (std::int64_t& modificationTime, std::int64_t& accessTime, std::int64_t& creationTime) const
|
||||
{
|
||||
using namespace WindowsFileHelpers;
|
||||
WIN32_FILE_ATTRIBUTE_DATA attributes;
|
||||
@@ -495,7 +495,7 @@ void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int
|
||||
}
|
||||
}
|
||||
|
||||
bool File::setFileTimesInternal (int64 modificationTime, int64 accessTime, int64 creationTime) const
|
||||
bool File::setFileTimesInternal (std::int64_t modificationTime, std::int64_t accessTime, std::int64_t creationTime) const
|
||||
{
|
||||
using namespace WindowsFileHelpers;
|
||||
|
||||
@@ -564,12 +564,12 @@ int File::getVolumeSerialNumber() const
|
||||
return (int) serialNum;
|
||||
}
|
||||
|
||||
int64 File::getBytesFreeOnVolume() const
|
||||
std::int64_t File::getBytesFreeOnVolume() const
|
||||
{
|
||||
return WindowsFileHelpers::getDiskSpaceInfo (getFullPathName(), false);
|
||||
}
|
||||
|
||||
int64 File::getVolumeTotalSize() const
|
||||
std::int64_t File::getVolumeTotalSize() const
|
||||
{
|
||||
return WindowsFileHelpers::getDiskSpaceInfo (getFullPathName(), true);
|
||||
}
|
||||
@@ -607,7 +607,7 @@ bool File::isOnRemovableDrive() const
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
File BEAST_CALLTYPE File::getSpecialLocation (const SpecialLocationType type)
|
||||
File File::getSpecialLocation (const SpecialLocationType type)
|
||||
{
|
||||
int csidlType = 0;
|
||||
|
||||
@@ -751,7 +751,7 @@ public:
|
||||
}
|
||||
|
||||
bool next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, int64* const fileSize,
|
||||
bool* const isDir, bool* const isHidden, std::int64_t* const fileSize,
|
||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
|
||||
{
|
||||
using namespace WindowsFileHelpers;
|
||||
@@ -775,7 +775,7 @@ public:
|
||||
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 + (((int64) findData.nFileSizeHigh) << 32);
|
||||
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));
|
||||
|
||||
@@ -797,7 +797,7 @@ DirectoryIterator::NativeIterator::~NativeIterator()
|
||||
}
|
||||
|
||||
bool DirectoryIterator::NativeIterator::next (String& filenameFound,
|
||||
bool* const isDir, bool* const isHidden, int64* const fileSize,
|
||||
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);
|
||||
|
||||
@@ -1,67 +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
|
||||
{
|
||||
|
||||
bool Process::openEmailWithAttachments (const String& targetEmailAddress,
|
||||
const String& emailSubject,
|
||||
const String& bodyText,
|
||||
const StringArray& filesToAttach)
|
||||
{
|
||||
DynamicLibrary dll ("MAPI32.dll");
|
||||
BEAST_LOAD_WINAPI_FUNCTION (dll, MAPISendMail, mapiSendMail,
|
||||
ULONG, (LHANDLE, ULONG, lpMapiMessage, ::FLAGS, ULONG))
|
||||
|
||||
if (mapiSendMail == nullptr)
|
||||
return false;
|
||||
|
||||
MapiMessage message = { 0 };
|
||||
message.lpszSubject = (LPSTR) emailSubject.toRawUTF8();
|
||||
message.lpszNoteText = (LPSTR) bodyText.toRawUTF8();
|
||||
|
||||
MapiRecipDesc recip = { 0 };
|
||||
recip.ulRecipClass = MAPI_TO;
|
||||
String targetEmailAddress_ (targetEmailAddress);
|
||||
if (targetEmailAddress_.isEmpty())
|
||||
targetEmailAddress_ = " "; // (Windows Mail can't deal with a blank address)
|
||||
recip.lpszName = (LPSTR) targetEmailAddress_.toRawUTF8();
|
||||
message.nRecipCount = 1;
|
||||
message.lpRecips = &recip;
|
||||
|
||||
HeapBlock <MapiFileDesc> files;
|
||||
files.calloc ((size_t) filesToAttach.size());
|
||||
|
||||
message.nFileCount = (ULONG) filesToAttach.size();
|
||||
message.lpFiles = files;
|
||||
|
||||
for (int i = 0; i < filesToAttach.size(); ++i)
|
||||
{
|
||||
files[i].nPosition = (ULONG) -1;
|
||||
files[i].lpszPathName = (LPSTR) filesToAttach[i].toRawUTF8();
|
||||
}
|
||||
|
||||
return mapiSendMail (0, 0, &message, MAPI_DIALOG | MAPI_LOGON_UI, 0) == SUCCESS_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
@@ -72,7 +72,7 @@ struct RegistryKeyWrapper : public Uncopyable
|
||||
(DWORD) dataSize) == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32 getBinaryValue (const String& regValuePath, MemoryBlock& result, DWORD wow64Flags)
|
||||
static std::uint32_t getBinaryValue (const String& regValuePath, MemoryBlock& result, DWORD wow64Flags)
|
||||
{
|
||||
const RegistryKeyWrapper key (regValuePath, false, wow64Flags);
|
||||
|
||||
@@ -135,7 +135,7 @@ struct RegistryKeyWrapper : public Uncopyable
|
||||
String valueName;
|
||||
};
|
||||
|
||||
uint32 WindowsRegistry::getBinaryValue (const String& regValuePath, MemoryBlock& result)
|
||||
std::uint32_t WindowsRegistry::getBinaryValue (const String& regValuePath, MemoryBlock& result)
|
||||
{
|
||||
return RegistryKeyWrapper::getBinaryValue (regValuePath, result, 0);
|
||||
}
|
||||
@@ -161,12 +161,12 @@ bool WindowsRegistry::setValue (const String& regValuePath, const String& value)
|
||||
CharPointer_UTF16::getBytesRequiredFor (value.getCharPointer()));
|
||||
}
|
||||
|
||||
bool WindowsRegistry::setValue (const String& regValuePath, const uint32 value)
|
||||
bool WindowsRegistry::setValue (const String& regValuePath, const std::uint32_t value)
|
||||
{
|
||||
return RegistryKeyWrapper::setValue (regValuePath, REG_DWORD, &value, sizeof (value));
|
||||
}
|
||||
|
||||
bool WindowsRegistry::setValue (const String& regValuePath, const uint64 value)
|
||||
bool WindowsRegistry::setValue (const String& regValuePath, const std::uint64_t value)
|
||||
{
|
||||
return RegistryKeyWrapper::setValue (regValuePath, REG_QWORD, &value, sizeof (value));
|
||||
}
|
||||
@@ -216,4 +216,4 @@ bool WindowsRegistry::registerFileAssociation (const String& fileExtension,
|
||||
targetExecutable.getFullPathName() + "," + String (-iconResourceNumber)));
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -31,8 +31,8 @@ void Logger::outputDebugString (const String& text)
|
||||
|
||||
//==============================================================================
|
||||
#ifdef BEAST_DLL_BUILD
|
||||
BEAST_API void* beastDLL_malloc (size_t sz) { return std::malloc (sz); }
|
||||
BEAST_API void beastDLL_free (void* block) { std::free (block); }
|
||||
void* beastDLL_malloc (size_t sz) { return std::malloc (sz); }
|
||||
void beastDLL_free (void* block) { std::free (block); }
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
@@ -225,9 +225,9 @@ String SystemStats::getEnvironmentVariable (const String& name, const String& de
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
uint32 beast_millisecondsSinceStartup() noexcept
|
||||
std::uint32_t beast_millisecondsSinceStartup() noexcept
|
||||
{
|
||||
return (uint32) timeGetTime();
|
||||
return (std::uint32_t) timeGetTime();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
@@ -247,17 +247,17 @@ public:
|
||||
hiResTicksScaleFactor = 1000.0 / hiResTicksPerSecond;
|
||||
}
|
||||
|
||||
inline int64 getHighResolutionTicks() noexcept
|
||||
inline std::int64_t getHighResolutionTicks() noexcept
|
||||
{
|
||||
LARGE_INTEGER ticks;
|
||||
QueryPerformanceCounter (&ticks);
|
||||
|
||||
const int64 mainCounterAsHiResTicks = (beast_millisecondsSinceStartup() * hiResTicksPerSecond) / 1000;
|
||||
const int64 newOffset = mainCounterAsHiResTicks - ticks.QuadPart;
|
||||
const std::int64_t mainCounterAsHiResTicks = (beast_millisecondsSinceStartup() * hiResTicksPerSecond) / 1000;
|
||||
const std::int64_t newOffset = mainCounterAsHiResTicks - ticks.QuadPart;
|
||||
|
||||
// fix for a very obscure PCI hardware bug that can make the counter
|
||||
// sometimes jump forwards by a few seconds..
|
||||
const int64 offsetDrift = abs64 (newOffset - hiResTicksOffset);
|
||||
const std::int64_t offsetDrift = abs64 (newOffset - hiResTicksOffset);
|
||||
|
||||
if (offsetDrift > (hiResTicksPerSecond >> 1))
|
||||
hiResTicksOffset = newOffset;
|
||||
@@ -270,22 +270,22 @@ public:
|
||||
return getHighResolutionTicks() * hiResTicksScaleFactor;
|
||||
}
|
||||
|
||||
int64 hiResTicksPerSecond, hiResTicksOffset;
|
||||
std::int64_t hiResTicksPerSecond, hiResTicksOffset;
|
||||
double hiResTicksScaleFactor;
|
||||
};
|
||||
|
||||
static HiResCounterHandler hiResCounterHandler;
|
||||
|
||||
int64 Time::getHighResolutionTicksPerSecond() noexcept { return hiResCounterHandler.hiResTicksPerSecond; }
|
||||
int64 Time::getHighResolutionTicks() noexcept { return hiResCounterHandler.getHighResolutionTicks(); }
|
||||
std::int64_t Time::getHighResolutionTicksPerSecond() noexcept { return hiResCounterHandler.hiResTicksPerSecond; }
|
||||
std::int64_t Time::getHighResolutionTicks() noexcept { return hiResCounterHandler.getHighResolutionTicks(); }
|
||||
double Time::getMillisecondCounterHiRes() noexcept { return hiResCounterHandler.getMillisecondCounterHiRes(); }
|
||||
|
||||
//==============================================================================
|
||||
static int64 beast_getClockCycleCounter() noexcept
|
||||
static std::int64_t beast_getClockCycleCounter() noexcept
|
||||
{
|
||||
#if BEAST_USE_INTRINSICS
|
||||
// MS intrinsics version...
|
||||
return (int64) __rdtsc();
|
||||
return (std::int64_t) __rdtsc();
|
||||
|
||||
#elif BEAST_GCC
|
||||
// GNU inline asm version...
|
||||
@@ -302,7 +302,7 @@ static int64 beast_getClockCycleCounter() noexcept
|
||||
[lo] "m" (lo)
|
||||
: "cc", "eax", "ebx", "ecx", "edx", "memory");
|
||||
|
||||
return (int64) ((((uint64) hi) << 32) | lo);
|
||||
return (std::int64_t) ((((std::uint64_t) hi) << 32) | lo);
|
||||
#else
|
||||
// MSVC inline asm version...
|
||||
unsigned int hi = 0, lo = 0;
|
||||
@@ -316,14 +316,14 @@ static int64 beast_getClockCycleCounter() noexcept
|
||||
mov hi, edx
|
||||
}
|
||||
|
||||
return (int64) ((((uint64) hi) << 32) | lo);
|
||||
return (std::int64_t) ((((std::uint64_t) hi) << 32) | lo);
|
||||
#endif
|
||||
}
|
||||
|
||||
int SystemStats::getCpuSpeedInMegaherz()
|
||||
{
|
||||
const int64 cycles = beast_getClockCycleCounter();
|
||||
const uint32 millis = Time::getMillisecondCounter();
|
||||
const std::int64_t cycles = beast_getClockCycleCounter();
|
||||
const std::uint32_t millis = Time::getMillisecondCounter();
|
||||
int lastResult = 0;
|
||||
|
||||
for (;;)
|
||||
@@ -331,8 +331,8 @@ int SystemStats::getCpuSpeedInMegaherz()
|
||||
int n = 1000000;
|
||||
while (--n > 0) {}
|
||||
|
||||
const uint32 millisElapsed = Time::getMillisecondCounter() - millis;
|
||||
const int64 cyclesNow = beast_getClockCycleCounter();
|
||||
const std::uint32_t millisElapsed = Time::getMillisecondCounter() - millis;
|
||||
const std::int64_t cyclesNow = beast_getClockCycleCounter();
|
||||
|
||||
if (millisElapsed > 80)
|
||||
{
|
||||
@@ -420,4 +420,4 @@ String SystemStats::getDisplayLanguage()
|
||||
return "en";
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -111,7 +111,7 @@ bool beast_isRunningUnderDebugger()
|
||||
return IsDebuggerPresent() != FALSE;
|
||||
}
|
||||
|
||||
bool BEAST_CALLTYPE Process::isRunningUnderDebugger()
|
||||
bool Process::isRunningUnderDebugger()
|
||||
{
|
||||
return beast_isRunningUnderDebugger();
|
||||
}
|
||||
@@ -184,274 +184,6 @@ void* DynamicLibrary::getFunction (const String& functionName) noexcept
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class InterProcessLock::Pimpl
|
||||
{
|
||||
public:
|
||||
Pimpl (String name, const int timeOutMillisecs)
|
||||
: handle (0), refCount (1)
|
||||
{
|
||||
name = name.replaceCharacter ('\\', '/');
|
||||
handle = CreateMutexW (0, TRUE, ("Global\\" + name).toWideCharPointer());
|
||||
|
||||
// Not 100% sure why a global mutex sometimes can't be allocated, but if it fails, fall back to
|
||||
// a local one. (A local one also sometimes fails on other machines so neither type appears to be
|
||||
// universally reliable)
|
||||
if (handle == 0)
|
||||
handle = CreateMutexW (0, TRUE, ("Local\\" + name).toWideCharPointer());
|
||||
|
||||
if (handle != 0 && GetLastError() == ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
if (timeOutMillisecs == 0)
|
||||
{
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (WaitForSingleObject (handle, timeOutMillisecs < 0 ? INFINITE : timeOutMillisecs))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
case WAIT_ABANDONED:
|
||||
break;
|
||||
|
||||
case WAIT_TIMEOUT:
|
||||
default:
|
||||
close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~Pimpl()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
if (handle != 0)
|
||||
{
|
||||
ReleaseMutex (handle);
|
||||
CloseHandle (handle);
|
||||
handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE handle;
|
||||
int refCount;
|
||||
};
|
||||
|
||||
InterProcessLock::InterProcessLock (const String& name_)
|
||||
: name (name_)
|
||||
{
|
||||
}
|
||||
|
||||
InterProcessLock::~InterProcessLock()
|
||||
{
|
||||
}
|
||||
|
||||
bool InterProcessLock::enter (const int timeOutMillisecs)
|
||||
{
|
||||
const ScopedLock sl (lock);
|
||||
|
||||
if (pimpl == nullptr)
|
||||
{
|
||||
pimpl = new Pimpl (name, timeOutMillisecs);
|
||||
|
||||
if (pimpl->handle == 0)
|
||||
pimpl = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
pimpl->refCount++;
|
||||
}
|
||||
|
||||
return pimpl != nullptr;
|
||||
}
|
||||
|
||||
void InterProcessLock::exit()
|
||||
{
|
||||
const ScopedLock sl (lock);
|
||||
|
||||
// Trying to release the lock too many times!
|
||||
bassert (pimpl != nullptr);
|
||||
|
||||
if (pimpl != nullptr && --(pimpl->refCount) == 0)
|
||||
pimpl = nullptr;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class ChildProcess::ActiveProcess : LeakChecked <ChildProcess::ActiveProcess>, public Uncopyable
|
||||
{
|
||||
public:
|
||||
ActiveProcess (const String& command)
|
||||
: ok (false), readPipe (0), writePipe (0)
|
||||
{
|
||||
SECURITY_ATTRIBUTES securityAtts = { 0 };
|
||||
securityAtts.nLength = sizeof (securityAtts);
|
||||
securityAtts.bInheritHandle = TRUE;
|
||||
|
||||
if (CreatePipe (&readPipe, &writePipe, &securityAtts, 0)
|
||||
&& SetHandleInformation (readPipe, HANDLE_FLAG_INHERIT, 0))
|
||||
{
|
||||
STARTUPINFOW startupInfo = { 0 };
|
||||
startupInfo.cb = sizeof (startupInfo);
|
||||
startupInfo.hStdError = writePipe;
|
||||
startupInfo.hStdOutput = writePipe;
|
||||
startupInfo.dwFlags = STARTF_USESTDHANDLES;
|
||||
|
||||
ok = CreateProcess (nullptr, const_cast <LPWSTR> (command.toWideCharPointer()),
|
||||
nullptr, nullptr, TRUE, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
|
||||
nullptr, nullptr, &startupInfo, &processInfo) != FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
~ActiveProcess()
|
||||
{
|
||||
if (ok)
|
||||
{
|
||||
CloseHandle (processInfo.hThread);
|
||||
CloseHandle (processInfo.hProcess);
|
||||
}
|
||||
|
||||
if (readPipe != 0)
|
||||
CloseHandle (readPipe);
|
||||
|
||||
if (writePipe != 0)
|
||||
CloseHandle (writePipe);
|
||||
}
|
||||
|
||||
bool isRunning() const
|
||||
{
|
||||
return WaitForSingleObject (processInfo.hProcess, 0) != WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
int read (void* dest, int numNeeded) const
|
||||
{
|
||||
int total = 0;
|
||||
|
||||
while (ok && numNeeded > 0)
|
||||
{
|
||||
DWORD available = 0;
|
||||
|
||||
if (! PeekNamedPipe ((HANDLE) readPipe, nullptr, 0, nullptr, &available, nullptr))
|
||||
break;
|
||||
|
||||
const int numToDo = bmin ((int) available, numNeeded);
|
||||
|
||||
if (available == 0)
|
||||
{
|
||||
if (! isRunning())
|
||||
break;
|
||||
|
||||
Thread::yield();
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD numRead = 0;
|
||||
if (! ReadFile ((HANDLE) readPipe, dest, numToDo, &numRead, nullptr))
|
||||
break;
|
||||
|
||||
total += numRead;
|
||||
dest = addBytesToPointer (dest, numRead);
|
||||
numNeeded -= numRead;
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
bool killProcess() const
|
||||
{
|
||||
return TerminateProcess (processInfo.hProcess, 0) != FALSE;
|
||||
}
|
||||
|
||||
bool ok;
|
||||
|
||||
private:
|
||||
HANDLE readPipe, writePipe;
|
||||
PROCESS_INFORMATION processInfo;
|
||||
};
|
||||
|
||||
bool ChildProcess::start (const String& command)
|
||||
{
|
||||
activeProcess = new ActiveProcess (command);
|
||||
|
||||
if (! activeProcess->ok)
|
||||
activeProcess = nullptr;
|
||||
|
||||
return activeProcess != nullptr;
|
||||
}
|
||||
|
||||
bool ChildProcess::start (const StringArray& args)
|
||||
{
|
||||
return start (args.joinIntoString (" "));
|
||||
}
|
||||
|
||||
bool ChildProcess::isRunning() const
|
||||
{
|
||||
return activeProcess != nullptr && activeProcess->isRunning();
|
||||
}
|
||||
|
||||
int ChildProcess::readProcessOutput (void* dest, int numBytes)
|
||||
{
|
||||
return activeProcess != nullptr ? activeProcess->read (dest, numBytes) : 0;
|
||||
}
|
||||
|
||||
bool ChildProcess::kill()
|
||||
{
|
||||
return activeProcess == nullptr || activeProcess->killProcess();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct HighResolutionTimer::Pimpl : public Uncopyable
|
||||
{
|
||||
Pimpl (HighResolutionTimer& t) noexcept : owner (t), periodMs (0)
|
||||
{
|
||||
}
|
||||
|
||||
~Pimpl()
|
||||
{
|
||||
bassert (periodMs == 0);
|
||||
}
|
||||
|
||||
void start (int newPeriod)
|
||||
{
|
||||
if (newPeriod != periodMs)
|
||||
{
|
||||
stop();
|
||||
periodMs = newPeriod;
|
||||
|
||||
TIMECAPS tc;
|
||||
if (timeGetDevCaps (&tc, sizeof (tc)) == TIMERR_NOERROR)
|
||||
{
|
||||
const int actualPeriod = blimit ((int) tc.wPeriodMin, (int) tc.wPeriodMax, newPeriod);
|
||||
|
||||
timerID = timeSetEvent (actualPeriod, tc.wPeriodMin, callbackFunction, (DWORD_PTR) this,
|
||||
TIME_PERIODIC | TIME_CALLBACK_FUNCTION | 0x100 /*TIME_KILL_SYNCHRONOUS*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
periodMs = 0;
|
||||
timeKillEvent (timerID);
|
||||
}
|
||||
|
||||
HighResolutionTimer& owner;
|
||||
int periodMs;
|
||||
|
||||
private:
|
||||
unsigned int timerID;
|
||||
|
||||
static void __stdcall callbackFunction (UINT, UINT, DWORD_PTR userInfo, DWORD_PTR, DWORD_PTR)
|
||||
{
|
||||
if (Pimpl* const timer = reinterpret_cast<Pimpl*> (userInfo))
|
||||
if (timer->periodMs != 0)
|
||||
timer->owner.hiResTimerCallback();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -43,9 +43,9 @@ InputStream* FileInputSource::createInputStreamFor (const String& relatedItemPat
|
||||
return file.getSiblingFile (relatedItemPath).createInputStream();
|
||||
}
|
||||
|
||||
int64 FileInputSource::hashCode() const
|
||||
std::int64_t FileInputSource::hashCode() const
|
||||
{
|
||||
int64 h = file.hashCode();
|
||||
std::int64_t h = file.hashCode();
|
||||
|
||||
if (useFileTimeInHashGeneration)
|
||||
h ^= file.getLastModificationTime().toMilliseconds();
|
||||
@@ -53,4 +53,4 @@ int64 FileInputSource::hashCode() const
|
||||
return h;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace beast
|
||||
|
||||
@see InputSource
|
||||
*/
|
||||
class BEAST_API FileInputSource
|
||||
class FileInputSource
|
||||
: public InputSource
|
||||
, LeakChecked <FileInputSource>
|
||||
, public Uncopyable
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
|
||||
InputStream* createInputStream();
|
||||
InputStream* createInputStreamFor (const String& relatedItemPath);
|
||||
int64 hashCode() const;
|
||||
std::int64_t hashCode() const;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
@@ -60,6 +60,6 @@ private:
|
||||
bool useFileTimeInHashGeneration;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_FILEINPUTSOURCE_H_INCLUDED
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace beast
|
||||
|
||||
@see FileInputSource
|
||||
*/
|
||||
class BEAST_API InputSource : LeakChecked <InputSource>
|
||||
class InputSource : LeakChecked <InputSource>
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
@@ -63,9 +63,9 @@ public:
|
||||
|
||||
/** Returns a hash code that uniquely represents this item.
|
||||
*/
|
||||
virtual int64 hashCode() const = 0;
|
||||
virtual std::int64_t hashCode() const = 0;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_INPUTSOURCE_H_INCLUDED
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
namespace beast
|
||||
{
|
||||
|
||||
int64 InputStream::getNumBytesRemaining()
|
||||
std::int64_t InputStream::getNumBytesRemaining()
|
||||
{
|
||||
int64 len = getTotalLength();
|
||||
std::int64_t len = getTotalLength();
|
||||
|
||||
if (len >= 0)
|
||||
len -= getPosition();
|
||||
@@ -78,12 +78,12 @@ int InputStream::readInt()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 InputStream::readInt32()
|
||||
std::int32_t InputStream::readInt32()
|
||||
{
|
||||
char temp[4];
|
||||
|
||||
if (read (temp, 4) == 4)
|
||||
return (int32) ByteOrder::littleEndianInt (temp);
|
||||
return (std::int32_t) ByteOrder::littleEndianInt (temp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -98,19 +98,19 @@ int InputStream::readIntBigEndian()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 InputStream::readInt32BigEndian()
|
||||
std::int32_t InputStream::readInt32BigEndian()
|
||||
{
|
||||
char temp[4];
|
||||
|
||||
if (read (temp, 4) == 4)
|
||||
return (int32) ByteOrder::bigEndianInt (temp);
|
||||
return (std::int32_t) ByteOrder::bigEndianInt (temp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int InputStream::readCompressedInt()
|
||||
{
|
||||
const uint8 sizeByte = (uint8) readByte();
|
||||
const std::uint8_t sizeByte = (std::uint8_t) readByte();
|
||||
if (sizeByte == 0)
|
||||
return 0;
|
||||
|
||||
@@ -130,22 +130,22 @@ int InputStream::readCompressedInt()
|
||||
return (sizeByte >> 7) ? -num : num;
|
||||
}
|
||||
|
||||
int64 InputStream::readInt64()
|
||||
std::int64_t InputStream::readInt64()
|
||||
{
|
||||
union { uint8 asBytes[8]; uint64 asInt64; } n;
|
||||
union { std::uint8_t asBytes[8]; std::uint64_t asInt64; } n;
|
||||
|
||||
if (read (n.asBytes, 8) == 8)
|
||||
return (int64) ByteOrder::swapIfBigEndian (n.asInt64);
|
||||
return (std::int64_t) ByteOrder::swapIfBigEndian (n.asInt64);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64 InputStream::readInt64BigEndian()
|
||||
std::int64_t InputStream::readInt64BigEndian()
|
||||
{
|
||||
union { uint8 asBytes[8]; uint64 asInt64; } n;
|
||||
union { std::uint8_t asBytes[8]; std::uint64_t asInt64; } n;
|
||||
|
||||
if (read (n.asBytes, 8) == 8)
|
||||
return (int64) ByteOrder::swapIfLittleEndian (n.asInt64);
|
||||
return (std::int64_t) ByteOrder::swapIfLittleEndian (n.asInt64);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -153,29 +153,29 @@ int64 InputStream::readInt64BigEndian()
|
||||
float InputStream::readFloat()
|
||||
{
|
||||
// the union below relies on these types being the same size...
|
||||
static_bassert (sizeof (int32) == sizeof (float));
|
||||
union { int32 asInt; float asFloat; } n;
|
||||
n.asInt = (int32) readInt();
|
||||
static_bassert (sizeof (std::int32_t) == sizeof (float));
|
||||
union { std::int32_t asInt; float asFloat; } n;
|
||||
n.asInt = (std::int32_t) readInt();
|
||||
return n.asFloat;
|
||||
}
|
||||
|
||||
float InputStream::readFloatBigEndian()
|
||||
{
|
||||
union { int32 asInt; float asFloat; } n;
|
||||
n.asInt = (int32) readIntBigEndian();
|
||||
union { std::int32_t asInt; float asFloat; } n;
|
||||
n.asInt = (std::int32_t) readIntBigEndian();
|
||||
return n.asFloat;
|
||||
}
|
||||
|
||||
double InputStream::readDouble()
|
||||
{
|
||||
union { int64 asInt; double asDouble; } n;
|
||||
union { std::int64_t asInt; double asDouble; } n;
|
||||
n.asInt = readInt64();
|
||||
return n.asDouble;
|
||||
}
|
||||
|
||||
double InputStream::readDoubleBigEndian()
|
||||
{
|
||||
union { int64 asInt; double asDouble; } n;
|
||||
union { std::int64_t asInt; double asDouble; } n;
|
||||
n.asInt = readInt64BigEndian();
|
||||
return n.asDouble;
|
||||
}
|
||||
@@ -212,7 +212,7 @@ String InputStream::readNextLine()
|
||||
|
||||
if (data[i] == '\r')
|
||||
{
|
||||
const int64 lastPos = getPosition();
|
||||
const std::int64_t lastPos = getPosition();
|
||||
|
||||
if (readByte() != '\n')
|
||||
setPosition (lastPos);
|
||||
@@ -230,7 +230,7 @@ String InputStream::readNextLine()
|
||||
return String::fromUTF8 (data, (int) i);
|
||||
}
|
||||
|
||||
int InputStream::readIntoMemoryBlock (MemoryBlock& block, ssize_t numBytes)
|
||||
int InputStream::readIntoMemoryBlock (MemoryBlock& block, std::ptrdiff_t numBytes)
|
||||
{
|
||||
MemoryOutputStream mo (block, true);
|
||||
return mo.writeFromInputStream (*this, numBytes);
|
||||
@@ -244,15 +244,15 @@ String InputStream::readEntireStreamAsString()
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void InputStream::skipNextBytes (int64 numBytesToSkip)
|
||||
void InputStream::skipNextBytes (std::int64_t numBytesToSkip)
|
||||
{
|
||||
if (numBytesToSkip > 0)
|
||||
{
|
||||
const int skipBufferSize = (int) bmin (numBytesToSkip, (int64) 16384);
|
||||
const int skipBufferSize = (int) bmin (numBytesToSkip, (std::int64_t) 16384);
|
||||
HeapBlock<char> temp ((size_t) skipBufferSize);
|
||||
|
||||
while (numBytesToSkip > 0 && ! isExhausted())
|
||||
numBytesToSkip -= read (temp, (int) bmin (numBytesToSkip, (int64) skipBufferSize));
|
||||
numBytesToSkip -= read (temp, (int) bmin (numBytesToSkip, (std::int64_t) skipBufferSize));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,10 +268,10 @@ template <>
|
||||
short InputStream::readType <short> () { return readShort (); }
|
||||
|
||||
template <>
|
||||
int32 InputStream::readType <int32> () { return readInt32 (); }
|
||||
std::int32_t InputStream::readType <std::int32_t> () { return readInt32 (); }
|
||||
|
||||
template <>
|
||||
int64 InputStream::readType <int64> () { return readInt64 (); }
|
||||
std::int64_t InputStream::readType <std::int64_t> () { return readInt64 (); }
|
||||
|
||||
template <>
|
||||
unsigned char InputStream::readType <unsigned char> () { return static_cast <unsigned char> (readByte ()); }
|
||||
@@ -280,10 +280,10 @@ template <>
|
||||
unsigned short InputStream::readType <unsigned short> () { return static_cast <unsigned short> (readShort ()); }
|
||||
|
||||
template <>
|
||||
uint32 InputStream::readType <uint32> () { return static_cast <uint32> (readInt32 ()); }
|
||||
std::uint32_t InputStream::readType <std::uint32_t> () { return static_cast <std::uint32_t> (readInt32 ()); }
|
||||
|
||||
template <>
|
||||
uint64 InputStream::readType <uint64> () { return static_cast <uint64> (readInt64 ()); }
|
||||
std::uint64_t InputStream::readType <std::uint64_t> () { return static_cast <std::uint64_t> (readInt64 ()); }
|
||||
|
||||
template <>
|
||||
float InputStream::readType <float> () { return readFloat (); }
|
||||
@@ -300,10 +300,10 @@ template <>
|
||||
short InputStream::readTypeBigEndian <short> () { return readShortBigEndian (); }
|
||||
|
||||
template <>
|
||||
int32 InputStream::readTypeBigEndian <int32> () { return readInt32BigEndian (); }
|
||||
std::int32_t InputStream::readTypeBigEndian <std::int32_t> () { return readInt32BigEndian (); }
|
||||
|
||||
template <>
|
||||
int64 InputStream::readTypeBigEndian <int64> () { return readInt64BigEndian (); }
|
||||
std::int64_t InputStream::readTypeBigEndian <std::int64_t> () { return readInt64BigEndian (); }
|
||||
|
||||
template <>
|
||||
unsigned char InputStream::readTypeBigEndian <unsigned char> () { return static_cast <unsigned char> (readByte ()); }
|
||||
@@ -312,10 +312,10 @@ template <>
|
||||
unsigned short InputStream::readTypeBigEndian <unsigned short> () { return static_cast <unsigned short> (readShortBigEndian ()); }
|
||||
|
||||
template <>
|
||||
uint32 InputStream::readTypeBigEndian <uint32> () { return static_cast <uint32> (readInt32BigEndian ()); }
|
||||
std::uint32_t InputStream::readTypeBigEndian <std::uint32_t> () { return static_cast <std::uint32_t> (readInt32BigEndian ()); }
|
||||
|
||||
template <>
|
||||
uint64 InputStream::readTypeBigEndian <uint64> () { return static_cast <uint64> (readInt64BigEndian ()); }
|
||||
std::uint64_t InputStream::readTypeBigEndian <std::uint64_t> () { return static_cast <std::uint64_t> (readInt64BigEndian ()); }
|
||||
|
||||
template <>
|
||||
float InputStream::readTypeBigEndian <float> () { return readFloatBigEndian (); }
|
||||
@@ -323,4 +323,4 @@ float InputStream::readTypeBigEndian <float> () { return readFloatBigEndian ();
|
||||
template <>
|
||||
double InputStream::readTypeBigEndian <double> () { return readDoubleBigEndian (); }
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -37,7 +37,7 @@ class MemoryBlock;
|
||||
|
||||
@see OutputStream, FileInputStream
|
||||
*/
|
||||
class BEAST_API InputStream
|
||||
class InputStream
|
||||
: public Uncopyable
|
||||
, LeakChecked <InputStream>
|
||||
{
|
||||
@@ -55,13 +55,13 @@ public:
|
||||
|
||||
@see getNumBytesRemaining
|
||||
*/
|
||||
virtual int64 getTotalLength() = 0;
|
||||
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
|
||||
*/
|
||||
int64 getNumBytesRemaining();
|
||||
std::int64_t getNumBytesRemaining();
|
||||
|
||||
/** Returns true if the stream has no more data to read. */
|
||||
virtual bool isExhausted() = 0;
|
||||
@@ -113,8 +113,8 @@ public:
|
||||
virtual short readShort();
|
||||
|
||||
// VFALCO TODO Implement these functions
|
||||
//virtual int16 readInt16 ();
|
||||
//virtual uint16 readUInt16 ();
|
||||
//virtual std::int16_t readInt16 ();
|
||||
//virtual std::uint16_t readUInt16 ();
|
||||
|
||||
/** Reads two bytes from the stream as a little-endian 16-bit value.
|
||||
|
||||
@@ -135,11 +135,11 @@ public:
|
||||
|
||||
@see OutputStream::writeInt, readIntBigEndian
|
||||
*/
|
||||
virtual int32 readInt32();
|
||||
virtual std::int32_t readInt32();
|
||||
|
||||
// VFALCO TODO Implement these functions
|
||||
//virtual int16 readInt16BigEndian ();
|
||||
//virtual uint16 readUInt16BigEndian ();
|
||||
//virtual std::int16_t readInt16BigEndian ();
|
||||
//virtual std::uint16_t readUInt16BigEndian ();
|
||||
|
||||
// DEPRECATED, assumes sizeof(int) == 4!
|
||||
virtual int readInt();
|
||||
@@ -153,7 +153,7 @@ public:
|
||||
|
||||
@see OutputStream::writeIntBigEndian, readInt
|
||||
*/
|
||||
virtual int32 readInt32BigEndian();
|
||||
virtual std::int32_t readInt32BigEndian();
|
||||
|
||||
// DEPRECATED, assumes sizeof(int) == 4!
|
||||
virtual int readIntBigEndian();
|
||||
@@ -167,7 +167,7 @@ public:
|
||||
|
||||
@see OutputStream::writeInt64, readInt64BigEndian
|
||||
*/
|
||||
virtual int64 readInt64();
|
||||
virtual std::int64_t readInt64();
|
||||
|
||||
/** Reads eight bytes from the stream as a big-endian 64-bit value.
|
||||
|
||||
@@ -178,7 +178,7 @@ public:
|
||||
|
||||
@see OutputStream::writeInt64BigEndian, readInt64
|
||||
*/
|
||||
virtual int64 readInt64BigEndian();
|
||||
virtual std::int64_t readInt64BigEndian();
|
||||
|
||||
/** Reads four bytes as a 32-bit floating point value.
|
||||
|
||||
@@ -202,7 +202,7 @@ public:
|
||||
|
||||
/** 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 int64.
|
||||
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.
|
||||
|
||||
@@ -212,7 +212,7 @@ public:
|
||||
|
||||
/** 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 int64.
|
||||
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.
|
||||
|
||||
@@ -318,14 +318,14 @@ public:
|
||||
@returns the number of bytes that were added to the memory block
|
||||
*/
|
||||
virtual int readIntoMemoryBlock (MemoryBlock& destBlock,
|
||||
ssize_t maxNumBytesToRead = -1);
|
||||
std::ptrdiff_t maxNumBytesToRead = -1);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the offset of the next byte that will be read from the stream.
|
||||
|
||||
@see setPosition
|
||||
*/
|
||||
virtual int64 getPosition() = 0;
|
||||
virtual std::int64_t getPosition() = 0;
|
||||
|
||||
/** Tries to move the current read position of the stream.
|
||||
|
||||
@@ -339,7 +339,7 @@ public:
|
||||
@returns true if the stream manages to reposition itself correctly
|
||||
@see getPosition
|
||||
*/
|
||||
virtual bool setPosition (int64 newPosition) = 0;
|
||||
virtual bool setPosition (std::int64_t newPosition) = 0;
|
||||
|
||||
/** Reads and discards a number of bytes from the stream.
|
||||
|
||||
@@ -347,7 +347,7 @@ public:
|
||||
class will just keep reading data until the requisite number of bytes
|
||||
have been done.
|
||||
*/
|
||||
virtual void skipNextBytes (int64 numBytesToSkip);
|
||||
virtual void skipNextBytes (std::int64_t numBytesToSkip);
|
||||
|
||||
|
||||
protected:
|
||||
@@ -355,6 +355,6 @@ protected:
|
||||
InputStream() noexcept {}
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -77,7 +77,7 @@ void MemoryOutputStream::reset() noexcept
|
||||
|
||||
char* MemoryOutputStream::prepareToWrite (size_t numBytes)
|
||||
{
|
||||
bassert ((ssize_t) numBytes >= 0);
|
||||
bassert ((std::ptrdiff_t) numBytes >= 0);
|
||||
size_t storageNeeded = position + numBytes;
|
||||
|
||||
char* data;
|
||||
@@ -119,7 +119,7 @@ bool MemoryOutputStream::write (const void* const buffer, size_t howMany)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MemoryOutputStream::writeRepeatedByte (uint8 byte, size_t howMany)
|
||||
bool MemoryOutputStream::writeRepeatedByte (std::uint8_t byte, size_t howMany)
|
||||
{
|
||||
if (howMany == 0)
|
||||
return true;
|
||||
@@ -160,9 +160,9 @@ const void* MemoryOutputStream::getData() const noexcept
|
||||
return blockToUse->getData();
|
||||
}
|
||||
|
||||
bool MemoryOutputStream::setPosition (int64 newPosition)
|
||||
bool MemoryOutputStream::setPosition (std::int64_t newPosition)
|
||||
{
|
||||
if (newPosition <= (int64) size)
|
||||
if (newPosition <= (std::int64_t) size)
|
||||
{
|
||||
// ok to seek backwards
|
||||
position = blimit ((size_t) 0, size, (size_t) newPosition);
|
||||
@@ -173,10 +173,10 @@ bool MemoryOutputStream::setPosition (int64 newPosition)
|
||||
return false;
|
||||
}
|
||||
|
||||
int MemoryOutputStream::writeFromInputStream (InputStream& source, int64 maxNumBytesToWrite)
|
||||
int MemoryOutputStream::writeFromInputStream (InputStream& source, std::int64_t maxNumBytesToWrite)
|
||||
{
|
||||
// before writing from an input, see if we can preallocate to make it more efficient..
|
||||
int64 availableData = source.getTotalLength() - source.getPosition();
|
||||
std::int64_t availableData = source.getTotalLength() - source.getPosition();
|
||||
|
||||
if (availableData > 0)
|
||||
{
|
||||
@@ -201,7 +201,7 @@ String MemoryOutputStream::toString() const
|
||||
return String::createStringFromData (getData(), (int) getDataSize());
|
||||
}
|
||||
|
||||
OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const MemoryOutputStream& streamToRead)
|
||||
OutputStream& operator<< (OutputStream& stream, const MemoryOutputStream& streamToRead)
|
||||
{
|
||||
const size_t dataSize = streamToRead.getDataSize();
|
||||
|
||||
@@ -211,4 +211,4 @@ OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const MemoryOutpu
|
||||
return stream;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace beast
|
||||
The data that was written into the stream can then be accessed later as
|
||||
a contiguous block of memory.
|
||||
*/
|
||||
class BEAST_API MemoryOutputStream
|
||||
class MemoryOutputStream
|
||||
: public OutputStream
|
||||
, LeakChecked <MemoryOutputStream>
|
||||
{
|
||||
@@ -121,10 +121,10 @@ public:
|
||||
void flush();
|
||||
|
||||
bool write (const void*, size_t) override;
|
||||
int64 getPosition() override { return position; }
|
||||
bool setPosition (int64) override;
|
||||
int writeFromInputStream (InputStream&, int64 maxNumBytesToWrite) override;
|
||||
bool writeRepeatedByte (uint8 byte, size_t numTimesToRepeat) 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();
|
||||
@@ -138,8 +138,8 @@ private:
|
||||
};
|
||||
|
||||
/** Copies all the data that has been written to a MemoryOutputStream into another stream. */
|
||||
OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const MemoryOutputStream& streamToRead);
|
||||
OutputStream& operator<< (OutputStream& stream, const MemoryOutputStream& streamToRead);
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -75,7 +75,7 @@ bool OutputStream::writeByte (char byte)
|
||||
return write (&byte, 1);
|
||||
}
|
||||
|
||||
bool OutputStream::writeRepeatedByte (uint8 byte, size_t numTimesToRepeat)
|
||||
bool OutputStream::writeRepeatedByte (std::uint8_t byte, size_t numTimesToRepeat)
|
||||
{
|
||||
for (size_t i = 0; i < numTimesToRepeat; ++i)
|
||||
if (! writeByte ((char) byte))
|
||||
@@ -96,11 +96,11 @@ bool OutputStream::writeShortBigEndian (short value)
|
||||
return write (&v, 2);
|
||||
}
|
||||
|
||||
bool OutputStream::writeInt32 (int32 value)
|
||||
bool OutputStream::writeInt32 (std::int32_t value)
|
||||
{
|
||||
static_bassert (sizeof (int32) == 4);
|
||||
static_bassert (sizeof (std::int32_t) == 4);
|
||||
|
||||
const unsigned int v = ByteOrder::swapIfBigEndian ((uint32) value);
|
||||
const unsigned int v = ByteOrder::swapIfBigEndian ((std::uint32_t) value);
|
||||
return write (&v, 4);
|
||||
}
|
||||
|
||||
@@ -114,8 +114,8 @@ bool OutputStream::writeInt (int value)
|
||||
|
||||
bool OutputStream::writeInt32BigEndian (int value)
|
||||
{
|
||||
static_bassert (sizeof (int32) == 4);
|
||||
const uint32 v = ByteOrder::swapIfLittleEndian ((uint32) value);
|
||||
static_bassert (sizeof (std::int32_t) == 4);
|
||||
const std::uint32_t v = ByteOrder::swapIfLittleEndian ((std::uint32_t) value);
|
||||
return write (&v, 4);
|
||||
}
|
||||
|
||||
@@ -131,16 +131,16 @@ bool OutputStream::writeCompressedInt (int value)
|
||||
unsigned int un = (value < 0) ? (unsigned int) -value
|
||||
: (unsigned int) value;
|
||||
|
||||
uint8 data[5];
|
||||
std::uint8_t data[5];
|
||||
int num = 0;
|
||||
|
||||
while (un > 0)
|
||||
{
|
||||
data[++num] = (uint8) un;
|
||||
data[++num] = (std::uint8_t) un;
|
||||
un >>= 8;
|
||||
}
|
||||
|
||||
data[0] = (uint8) num;
|
||||
data[0] = (std::uint8_t) num;
|
||||
|
||||
if (value < 0)
|
||||
data[0] |= 0x80;
|
||||
@@ -148,15 +148,15 @@ bool OutputStream::writeCompressedInt (int value)
|
||||
return write (data, (size_t) num + 1);
|
||||
}
|
||||
|
||||
bool OutputStream::writeInt64 (int64 value)
|
||||
bool OutputStream::writeInt64 (std::int64_t value)
|
||||
{
|
||||
const uint64 v = ByteOrder::swapIfBigEndian ((uint64) value);
|
||||
const std::uint64_t v = ByteOrder::swapIfBigEndian ((std::uint64_t) value);
|
||||
return write (&v, 8);
|
||||
}
|
||||
|
||||
bool OutputStream::writeInt64BigEndian (int64 value)
|
||||
bool OutputStream::writeInt64BigEndian (std::int64_t value)
|
||||
{
|
||||
const uint64 v = ByteOrder::swapIfLittleEndian ((uint64) value);
|
||||
const std::uint64_t v = ByteOrder::swapIfLittleEndian ((std::uint64_t) value);
|
||||
return write (&v, 8);
|
||||
}
|
||||
|
||||
@@ -176,14 +176,14 @@ bool OutputStream::writeFloatBigEndian (float value)
|
||||
|
||||
bool OutputStream::writeDouble (double value)
|
||||
{
|
||||
union { int64 asInt; double asDouble; } n;
|
||||
union { std::int64_t asInt; double asDouble; } n;
|
||||
n.asDouble = value;
|
||||
return writeInt64 (n.asInt);
|
||||
}
|
||||
|
||||
bool OutputStream::writeDoubleBigEndian (double value)
|
||||
{
|
||||
union { int64 asInt; double asDouble; } n;
|
||||
union { std::int64_t asInt; double asDouble; } n;
|
||||
n.asDouble = value;
|
||||
return writeInt64BigEndian (n.asInt);
|
||||
}
|
||||
@@ -264,17 +264,17 @@ bool OutputStream::writeText (const String& text, const bool asUTF16,
|
||||
return true;
|
||||
}
|
||||
|
||||
int OutputStream::writeFromInputStream (InputStream& source, int64 numBytesToWrite)
|
||||
int OutputStream::writeFromInputStream (InputStream& source, std::int64_t numBytesToWrite)
|
||||
{
|
||||
if (numBytesToWrite < 0)
|
||||
numBytesToWrite = std::numeric_limits<int64>::max();
|
||||
numBytesToWrite = std::numeric_limits<std::int64_t>::max();
|
||||
|
||||
int numWritten = 0;
|
||||
|
||||
while (numBytesToWrite > 0)
|
||||
{
|
||||
char buffer [8192];
|
||||
const int num = source.read (buffer, (int) bmin (numBytesToWrite, (int64) sizeof (buffer)));
|
||||
const int num = source.read (buffer, (int) bmin (numBytesToWrite, (std::int64_t) sizeof (buffer)));
|
||||
|
||||
if (num <= 0)
|
||||
break;
|
||||
@@ -295,34 +295,34 @@ void OutputStream::setNewLineString (const String& newLineString_)
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const int number)
|
||||
OutputStream& operator<< (OutputStream& stream, const int number)
|
||||
{
|
||||
return stream << String (number);
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const int64 number)
|
||||
OutputStream& operator<< (OutputStream& stream, const std::int64_t number)
|
||||
{
|
||||
return stream << String (number);
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const double number)
|
||||
OutputStream& operator<< (OutputStream& stream, const double number)
|
||||
{
|
||||
return stream << String (number);
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const char character)
|
||||
OutputStream& operator<< (OutputStream& stream, const char character)
|
||||
{
|
||||
stream.writeByte (character);
|
||||
return stream;
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const char* const text)
|
||||
OutputStream& operator<< (OutputStream& stream, const char* const text)
|
||||
{
|
||||
stream.write (text, strlen (text));
|
||||
return stream;
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const MemoryBlock& data)
|
||||
OutputStream& operator<< (OutputStream& stream, const MemoryBlock& data)
|
||||
{
|
||||
if (data.getSize() > 0)
|
||||
stream.write (data.getData(), data.getSize());
|
||||
@@ -330,7 +330,7 @@ BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const M
|
||||
return stream;
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const File& fileToRead)
|
||||
OutputStream& operator<< (OutputStream& stream, const File& fileToRead)
|
||||
{
|
||||
FileInputStream in (fileToRead);
|
||||
|
||||
@@ -340,13 +340,13 @@ BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const F
|
||||
return stream;
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, InputStream& streamToRead)
|
||||
OutputStream& operator<< (OutputStream& stream, InputStream& streamToRead)
|
||||
{
|
||||
stream.writeFromInputStream (streamToRead, -1);
|
||||
return stream;
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const NewLine&)
|
||||
OutputStream& operator<< (OutputStream& stream, const NewLine&)
|
||||
{
|
||||
return stream << stream.getNewLineString();
|
||||
}
|
||||
@@ -357,68 +357,68 @@ BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const N
|
||||
// definition linker errors, even with the inline keyword!
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeType <char> (char v) { return writeByte (v); }
|
||||
bool OutputStream::writeType <char> (char v) { return writeByte (v); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeType <short> (short v) { return writeShort (v); }
|
||||
bool OutputStream::writeType <short> (short v) { return writeShort (v); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeType <int32> (int32 v) { return writeInt32 (v); }
|
||||
bool OutputStream::writeType <std::int32_t> (std::int32_t v) { return writeInt32 (v); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeType <int64> (int64 v) { return writeInt64 (v); }
|
||||
bool OutputStream::writeType <std::int64_t> (std::int64_t v) { return writeInt64 (v); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeType <unsigned char> (unsigned char v) { return writeByte (static_cast <char> (v)); }
|
||||
bool OutputStream::writeType <unsigned char> (unsigned char v) { return writeByte (static_cast <char> (v)); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeType <unsigned short> (unsigned short v) { return writeShort (static_cast <short> (v)); }
|
||||
bool OutputStream::writeType <unsigned short> (unsigned short v) { return writeShort (static_cast <short> (v)); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeType <uint32> (uint32 v) { return writeInt32 (static_cast <int32> (v)); }
|
||||
bool OutputStream::writeType <std::uint32_t> (std::uint32_t v) { return writeInt32 (static_cast <std::int32_t> (v)); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeType <uint64> (uint64 v) { return writeInt64 (static_cast <int64> (v)); }
|
||||
bool OutputStream::writeType <std::uint64_t> (std::uint64_t v) { return writeInt64 (static_cast <std::int64_t> (v)); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeType <float> (float v) { return writeFloat (v); }
|
||||
bool OutputStream::writeType <float> (float v) { return writeFloat (v); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeType <double> (double v) { return writeDouble (v); }
|
||||
bool OutputStream::writeType <double> (double v) { return writeDouble (v); }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeTypeBigEndian <char> (char v) { return writeByte (v); }
|
||||
bool OutputStream::writeTypeBigEndian <char> (char v) { return writeByte (v); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeTypeBigEndian <short> (short v) { return writeShortBigEndian (v); }
|
||||
bool OutputStream::writeTypeBigEndian <short> (short v) { return writeShortBigEndian (v); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeTypeBigEndian <int32> (int32 v) { return writeInt32BigEndian (v); }
|
||||
bool OutputStream::writeTypeBigEndian <std::int32_t> (std::int32_t v) { return writeInt32BigEndian (v); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeTypeBigEndian <int64> (int64 v) { return writeInt64BigEndian (v); }
|
||||
bool OutputStream::writeTypeBigEndian <std::int64_t> (std::int64_t v) { return writeInt64BigEndian (v); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeTypeBigEndian <unsigned char> (unsigned char v) { return writeByte (static_cast <char> (v)); }
|
||||
bool OutputStream::writeTypeBigEndian <unsigned char> (unsigned char v) { return writeByte (static_cast <char> (v)); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeTypeBigEndian <unsigned short> (unsigned short v) { return writeShortBigEndian (static_cast <short> (v)); }
|
||||
bool OutputStream::writeTypeBigEndian <unsigned short> (unsigned short v) { return writeShortBigEndian (static_cast <short> (v)); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeTypeBigEndian <uint32> (uint32 v) { return writeInt32BigEndian (static_cast <int32> (v)); }
|
||||
bool OutputStream::writeTypeBigEndian <std::uint32_t> (std::uint32_t v) { return writeInt32BigEndian (static_cast <std::int32_t> (v)); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeTypeBigEndian <uint64> (uint64 v) { return writeInt64BigEndian (static_cast <int64> (v)); }
|
||||
bool OutputStream::writeTypeBigEndian <std::uint64_t> (std::uint64_t v) { return writeInt64BigEndian (static_cast <std::int64_t> (v)); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeTypeBigEndian <float> (float v) { return writeFloatBigEndian (v); }
|
||||
bool OutputStream::writeTypeBigEndian <float> (float v) { return writeFloatBigEndian (v); }
|
||||
|
||||
template <>
|
||||
BEAST_API bool OutputStream::writeTypeBigEndian <double> (double v) { return writeDoubleBigEndian (v); }
|
||||
bool OutputStream::writeTypeBigEndian <double> (double v) { return writeDoubleBigEndian (v); }
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const String& text)
|
||||
OutputStream& operator<< (OutputStream& stream, const String& text)
|
||||
{
|
||||
const size_t numBytes = text.getNumBytesAsUTF8();
|
||||
|
||||
@@ -435,4 +435,4 @@ BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const S
|
||||
return stream;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -40,7 +40,7 @@ class File;
|
||||
|
||||
@see InputStream, MemoryOutputStream, FileOutputStream
|
||||
*/
|
||||
class BEAST_API OutputStream : public Uncopyable
|
||||
class OutputStream : public Uncopyable
|
||||
{
|
||||
protected:
|
||||
//==============================================================================
|
||||
@@ -66,13 +66,13 @@ public:
|
||||
|
||||
@see getPosition
|
||||
*/
|
||||
virtual bool setPosition (int64 newPosition) = 0;
|
||||
virtual bool setPosition (std::int64_t newPosition) = 0;
|
||||
|
||||
/** Returns the stream's current position.
|
||||
|
||||
@see setPosition
|
||||
*/
|
||||
virtual int64 getPosition() = 0;
|
||||
virtual std::int64_t getPosition() = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** Writes a block of data to the stream.
|
||||
@@ -120,7 +120,7 @@ public:
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readInt
|
||||
*/
|
||||
virtual bool writeInt32 (int32 value);
|
||||
virtual bool writeInt32 (std::int32_t value);
|
||||
|
||||
// DEPRECATED, assumes sizeof (int) == 4!
|
||||
virtual bool writeInt (int value);
|
||||
@@ -129,7 +129,7 @@ public:
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readIntBigEndian
|
||||
*/
|
||||
virtual bool writeInt32BigEndian (int32 value);
|
||||
virtual bool writeInt32BigEndian (std::int32_t value);
|
||||
|
||||
// DEPRECATED, assumes sizeof (int) == 4!
|
||||
virtual bool writeIntBigEndian (int value);
|
||||
@@ -138,13 +138,13 @@ public:
|
||||
@returns false if the write operation fails for some reason
|
||||
@see InputStream::readInt64
|
||||
*/
|
||||
virtual bool writeInt64 (int64 value);
|
||||
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 (int64 value);
|
||||
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.
|
||||
@@ -194,7 +194,7 @@ public:
|
||||
/** 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 (uint8 byte, size_t numTimesToRepeat);
|
||||
virtual bool writeRepeatedByte (std::uint8_t byte, size_t numTimesToRepeat);
|
||||
|
||||
/** Writes a condensed binary encoding of a 32-bit integer.
|
||||
|
||||
@@ -245,7 +245,7 @@ public:
|
||||
is exhausted)
|
||||
@returns the number of bytes written
|
||||
*/
|
||||
virtual int writeFromInputStream (InputStream& source, int64 maxNumBytesToWrite);
|
||||
virtual int writeFromInputStream (InputStream& source, std::int64_t maxNumBytesToWrite);
|
||||
|
||||
//==============================================================================
|
||||
/** Sets the string that will be written to the stream when the writeNewLine()
|
||||
@@ -264,28 +264,28 @@ private:
|
||||
|
||||
//==============================================================================
|
||||
/** Writes a number to a stream as 8-bit characters in the default system encoding. */
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, int number);
|
||||
OutputStream& operator<< (OutputStream& stream, int number);
|
||||
|
||||
/** Writes a number to a stream as 8-bit characters in the default system encoding. */
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, int64 number);
|
||||
OutputStream& operator<< (OutputStream& stream, std::int64_t number);
|
||||
|
||||
/** Writes a number to a stream as 8-bit characters in the default system encoding. */
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, double number);
|
||||
OutputStream& operator<< (OutputStream& stream, double number);
|
||||
|
||||
/** Writes a character to a stream. */
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, char character);
|
||||
OutputStream& operator<< (OutputStream& stream, char character);
|
||||
|
||||
/** Writes a null-terminated text string to a stream. */
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const char* text);
|
||||
OutputStream& operator<< (OutputStream& stream, const char* text);
|
||||
|
||||
/** Writes a block of data from a MemoryBlock to a stream. */
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const MemoryBlock& data);
|
||||
OutputStream& operator<< (OutputStream& stream, const MemoryBlock& data);
|
||||
|
||||
/** Writes the contents of a file to a stream. */
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const File& fileToRead);
|
||||
OutputStream& operator<< (OutputStream& stream, const File& fileToRead);
|
||||
|
||||
/** Writes the complete contents of an input stream to an output stream. */
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, InputStream& streamToRead);
|
||||
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.
|
||||
@@ -294,11 +294,11 @@ BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, InputSt
|
||||
@endcode
|
||||
@see OutputStream::setNewLineString
|
||||
*/
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const NewLine&);
|
||||
OutputStream& operator<< (OutputStream& stream, const NewLine&);
|
||||
|
||||
/** Writes a string to an OutputStream as UTF8. */
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const String& stringToWrite);
|
||||
OutputStream& operator<< (OutputStream& stream, const String& stringToWrite);
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -376,6 +376,6 @@ using namespace placeholders;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,15 +28,15 @@ String SystemStats::getBeastVersion()
|
||||
{
|
||||
// Some basic tests, to keep an eye on things and make sure these types work ok
|
||||
// on all platforms. Let me know if any of these assertions fail on your system!
|
||||
static_bassert (sizeof (pointer_sized_int) == sizeof (void*));
|
||||
static_bassert (sizeof (int8) == 1);
|
||||
static_bassert (sizeof (uint8) == 1);
|
||||
static_bassert (sizeof (int16) == 2);
|
||||
static_bassert (sizeof (uint16) == 2);
|
||||
static_bassert (sizeof (int32) == 4);
|
||||
static_bassert (sizeof (uint32) == 4);
|
||||
static_bassert (sizeof (int64) == 8);
|
||||
static_bassert (sizeof (uint64) == 8);
|
||||
static_bassert (sizeof (std::intptr_t) == sizeof (void*));
|
||||
static_bassert (sizeof (std::int8_t) == 1);
|
||||
static_bassert (sizeof (std::uint8_t) == 1);
|
||||
static_bassert (sizeof (std::int16_t) == 2);
|
||||
static_bassert (sizeof (std::uint16_t) == 2);
|
||||
static_bassert (sizeof (std::int32_t) == 4);
|
||||
static_bassert (sizeof (std::uint32_t) == 4);
|
||||
static_bassert (sizeof (std::int64_t) == 8);
|
||||
static_bassert (sizeof (std::uint64_t) == 8);
|
||||
|
||||
return "Beast v" BEAST_STRINGIFY(BEAST_MAJOR_VERSION)
|
||||
"." BEAST_STRINGIFY(BEAST_MINOR_VERSION)
|
||||
@@ -107,7 +107,7 @@ String SystemStats::getStackBacktrace()
|
||||
if (::SymGetModuleInfo64 (process, symbol->ModBase, &moduleInfo))
|
||||
result << moduleInfo.ModuleName << ": ";
|
||||
|
||||
result << symbol->Name << " + 0x" << String::toHexString ((int64) displacement) << newLine;
|
||||
result << symbol->Name << " + 0x" << String::toHexString ((std::int64_t) displacement) << newLine;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,4 +162,4 @@ void SystemStats::setApplicationCrashHandler (CrashHandlerFunction handler)
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace beast
|
||||
/**
|
||||
Contains methods for finding out about the current hardware and OS configuration.
|
||||
*/
|
||||
class BEAST_API SystemStats : public Uncopyable
|
||||
class SystemStats : public Uncopyable
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
@@ -180,6 +180,6 @@ private:
|
||||
SystemStats();
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_SYSTEMSTATS_H_INCLUDED
|
||||
|
||||
@@ -107,7 +107,7 @@ public:
|
||||
|
||||
void run()
|
||||
{
|
||||
int64 const seedValue = 50;
|
||||
std::int64_t const seedValue = 50;
|
||||
|
||||
Random r (seedValue);
|
||||
|
||||
@@ -115,10 +115,10 @@ public:
|
||||
testIntegers <unsigned int> (r);
|
||||
testIntegers <short> (r);
|
||||
testIntegers <unsigned short> (r);
|
||||
testIntegers <int32> (r);
|
||||
testIntegers <uint32> (r);
|
||||
testIntegers <int64> (r);
|
||||
testIntegers <uint64> (r);
|
||||
testIntegers <std::int32_t> (r);
|
||||
testIntegers <std::uint32_t> (r);
|
||||
testIntegers <std::int64_t> (r);
|
||||
testIntegers <std::uint64_t> (r);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ struct LexicalCastUtilities
|
||||
if (0 == std::distance (begin, end))
|
||||
return false;
|
||||
|
||||
uint64 accum = 0;
|
||||
std::uint64_t accum = 0;
|
||||
InputIterator it = begin;
|
||||
|
||||
// process sign
|
||||
@@ -53,23 +53,23 @@ struct LexicalCastUtilities
|
||||
return false;
|
||||
|
||||
// calc max of abs value
|
||||
uint64 max;
|
||||
std::uint64_t max;
|
||||
if (negative)
|
||||
max = static_cast <uint64> (
|
||||
-(static_cast <int64> (std::numeric_limits <IntType>::min ())));
|
||||
max = static_cast <std::uint64_t> (
|
||||
-(static_cast <std::int64_t> (std::numeric_limits <IntType>::min ())));
|
||||
else
|
||||
max = std::numeric_limits <IntType>::max ();
|
||||
|
||||
// process digits
|
||||
while (end != it)
|
||||
{
|
||||
uint64 const digit = static_cast <IntType> (
|
||||
std::uint64_t const digit = static_cast <IntType> (
|
||||
s_digitTable [static_cast <unsigned int> (*it++)]);
|
||||
|
||||
if (0xFF == digit)
|
||||
return false;
|
||||
|
||||
uint64 const overflow = (max - digit) / 10;
|
||||
std::uint64_t const overflow = (max - digit) / 10;
|
||||
|
||||
if (accum > overflow)
|
||||
return false;
|
||||
@@ -95,20 +95,20 @@ struct LexicalCastUtilities
|
||||
if (0 == std::distance (begin, end))
|
||||
return false;
|
||||
|
||||
uint64 accum = 0;
|
||||
std::uint64_t accum = 0;
|
||||
InputIterator it = begin;
|
||||
uint64 const max = std::numeric_limits <IntType>::max ();
|
||||
std::uint64_t const max = std::numeric_limits <IntType>::max ();
|
||||
|
||||
// process digits
|
||||
while (end != it)
|
||||
{
|
||||
uint64 const digit = static_cast <IntType> (
|
||||
std::uint64_t const digit = static_cast <IntType> (
|
||||
s_digitTable [static_cast <unsigned int> (*it++)]);
|
||||
|
||||
if (0xFF == digit)
|
||||
return false;
|
||||
|
||||
uint64 const overflow = (max - digit) / 10;
|
||||
std::uint64_t const overflow = (max - digit) / 10;
|
||||
|
||||
if (accum > overflow)
|
||||
return false;
|
||||
@@ -143,8 +143,8 @@ struct LexicalCast <String, In>
|
||||
bool operator() (String& out, unsigned int in) const { out = String (in); return true; }
|
||||
bool operator() (String& out, short in) const { out = String (in); return true; }
|
||||
bool operator() (String& out, unsigned short in) const { out = String (in); return true; }
|
||||
bool operator() (String& out, int64 in) const { out = String (in); return true; }
|
||||
bool operator() (String& out, uint64 in) const { out = String (in); return true; }
|
||||
bool operator() (String& out, std::int64_t in) const { out = String (in); return true; }
|
||||
bool operator() (String& out, std::uint64_t in) const { out = String (in); return true; }
|
||||
bool operator() (String& out, float in) const { out = String (in); return true; }
|
||||
bool operator() (String& out, double in) const { out = String (in); return true; }
|
||||
};
|
||||
@@ -155,10 +155,10 @@ struct LexicalCast <Out, String>
|
||||
{
|
||||
bool operator() (int& out, String const& in) const { std::string const& s (in.toStdString ()); return LexicalCastUtilities::parseSigned (out, s.begin (), s.end ()); }
|
||||
bool operator() (short& out, String const& in) const { std::string const& s (in.toStdString ()); return LexicalCastUtilities::parseSigned (out, s.begin (), s.end ()); }
|
||||
bool operator() (int64& out, String const& in) const { std::string const& s (in.toStdString ()); return LexicalCastUtilities::parseSigned (out, s.begin (), s.end ()); }
|
||||
bool operator() (std::int64_t& out, String const& in) const { std::string const& s (in.toStdString ()); return LexicalCastUtilities::parseSigned (out, s.begin (), s.end ()); }
|
||||
bool operator() (unsigned int& out, String const& in) const { std::string const& s (in.toStdString ()); return LexicalCastUtilities::parseUnsigned (out, s.begin (), s.end ()); }
|
||||
bool operator() (unsigned short& out, String const& in) const { std::string const& s (in.toStdString ()); return LexicalCastUtilities::parseUnsigned (out, s.begin (), s.end ()); }
|
||||
bool operator() (uint64& out, String const& in) const { std::string const& s (in.toStdString ()); return LexicalCastUtilities::parseUnsigned (out, s.begin (), s.end ()); }
|
||||
bool operator() (std::uint64_t& out, String const& in) const { std::string const& s (in.toStdString ()); return LexicalCastUtilities::parseUnsigned (out, s.begin (), s.end ()); }
|
||||
bool operator() (float& out, String const& in) const { bassertfalse; return false; /* UNIMPLEMENTED! */ }
|
||||
bool operator() (double& out, String const& in) const { bassertfalse; return false; /* UNIMPLEMENTED! */ }
|
||||
|
||||
@@ -282,7 +282,7 @@ Out lexicalCastThrow (In in)
|
||||
if (lexicalCastChecked (out, in))
|
||||
return out;
|
||||
|
||||
Throw (BadLexicalCast (), __FILE__, __LINE__);
|
||||
throw BadLexicalCast ();
|
||||
|
||||
return Out ();
|
||||
}
|
||||
@@ -303,6 +303,6 @@ Out lexicalCast (In in, Out defaultValue = Out ())
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -512,4 +512,4 @@ void StringArray::minimiseStorageOverheads()
|
||||
strings.minimiseStorageOverheads();
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -24,8 +24,10 @@
|
||||
#ifndef BEAST_STRINGARRAY_H_INCLUDED
|
||||
#define BEAST_STRINGARRAY_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
#include "../containers/Array.h"
|
||||
#include "../threads/CriticalSection.h"
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
@@ -33,7 +35,7 @@ namespace beast
|
||||
|
||||
@see String, StringPairArray
|
||||
*/
|
||||
class BEAST_API StringArray : LeakChecked <StringArray>
|
||||
class StringArray : LeakChecked <StringArray>
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
@@ -407,6 +409,6 @@ private:
|
||||
Array <String> strings;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_STRINGARRAY_H_INCLUDED
|
||||
|
||||
@@ -146,4 +146,4 @@ void StringPairArray::minimiseStorageOverheads()
|
||||
values.minimiseStorageOverheads();
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -24,8 +24,10 @@
|
||||
#ifndef BEAST_STRINGPAIRARRAY_H_INCLUDED
|
||||
#define BEAST_STRINGPAIRARRAY_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
#include "StringArray.h"
|
||||
#include "../../../beast/utility/LeakChecked.h"
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
@@ -33,7 +35,7 @@ namespace beast
|
||||
|
||||
@see StringArray
|
||||
*/
|
||||
class BEAST_API StringPairArray : LeakChecked <StringPairArray>
|
||||
class StringPairArray : LeakChecked <StringPairArray>
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
@@ -155,6 +157,6 @@ private:
|
||||
bool ignoreCase;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_STRINGPAIRARRAY_H_INCLUDED
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
{
|
||||
bassert (secondsRecurring >= 0);
|
||||
|
||||
LockType::ScopedLockType lock (m_mutex);
|
||||
std::lock_guard <LockType> lock (m_mutex);
|
||||
|
||||
if (timer.m_isActive)
|
||||
{
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
//
|
||||
void deactivate (DeadlineTimer& timer)
|
||||
{
|
||||
LockType::ScopedLockType lock (m_mutex);
|
||||
std::lock_guard <LockType> lock (m_mutex);
|
||||
|
||||
if (timer.m_isActive)
|
||||
{
|
||||
@@ -96,7 +96,7 @@ public:
|
||||
DeadlineTimer* timer (nullptr);
|
||||
|
||||
{
|
||||
LockType::ScopedLockType lock (m_mutex);
|
||||
std::lock_guard <LockType> lock (m_mutex);
|
||||
|
||||
// See if a timer expired
|
||||
if (! m_items.empty ())
|
||||
@@ -245,4 +245,4 @@ void DeadlineTimer::setRecurringExpiration (double secondsUntilDeadline)
|
||||
m_manager->activate (*this, secondsUntilDeadline, when);
|
||||
}
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
@@ -111,6 +111,6 @@ private:
|
||||
double m_secondsRecurring; // non zero if recurring
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -75,6 +75,6 @@ struct MutexTraits <CriticalSection>
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,30 +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_CORE_THREAD_TRACKEDMUTEX_H_INCLUDED
|
||||
#define BEAST_CORE_THREAD_TRACKEDMUTEX_H_INCLUDED
|
||||
|
||||
#include "detail/TrackedMutex.h"
|
||||
#include "detail/ScopedLock.h"
|
||||
|
||||
#include "impl/TrackedMutex.h"
|
||||
#include "impl/TrackedMutexType.h"
|
||||
#include "impl/UntrackedMutexType.h"
|
||||
|
||||
#endif
|
||||
@@ -20,8 +20,10 @@
|
||||
#ifndef BEAST_WORKERS_H_INCLUDED
|
||||
#define BEAST_WORKERS_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
#include "../system/SystemStats.h"
|
||||
#include "../../../beast/threads/semaphore.h"
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A group of threads that process tasks.
|
||||
*/
|
||||
@@ -142,6 +144,6 @@ private:
|
||||
LockFreeStack <Worker, PausedTag> m_paused; // holds just paused workers
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -250,8 +250,8 @@ private:
|
||||
bool m_owns_lock;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // detail
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,101 +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_CORE_THREAD_DETAIL_TRACKEDMUTEX_H_INCLUDED
|
||||
#define BEAST_CORE_THREAD_DETAIL_TRACKEDMUTEX_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
class TrackedMutex;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct TrackedMutexBasics
|
||||
{
|
||||
struct PerThreadData;
|
||||
|
||||
typedef List <TrackedMutex> ThreadLockList;
|
||||
typedef List <PerThreadData> GlobalThreadList;
|
||||
|
||||
// Retrieve an atomic counter unique to class Object
|
||||
template <typename Object>
|
||||
static Atomic <int>& getCounter () noexcept
|
||||
{
|
||||
static Atomic <int> counter;
|
||||
return counter;
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
inline static String createName (String name,
|
||||
char const* fileName, int lineNumber)
|
||||
{
|
||||
return createName (name, fileName, lineNumber,
|
||||
++getCounter <Object> ());
|
||||
}
|
||||
|
||||
static String createName (String name,
|
||||
char const* fileName, int lineNumber, int instanceNumber = 0);
|
||||
|
||||
struct PerThreadData
|
||||
: GlobalThreadList::Node
|
||||
{
|
||||
PerThreadData ();
|
||||
|
||||
int id;
|
||||
int refCount;
|
||||
ThreadLockList list;
|
||||
CriticalSection mutex;
|
||||
|
||||
TrackedMutex const* blocked;
|
||||
String threadName; // at the time of the block
|
||||
String sourceLocation; // at the time of the block
|
||||
};
|
||||
|
||||
// This turns the thread local into a POD which will be
|
||||
// initialized to all zeroes. We use the 'id' flag to
|
||||
// know to initialize.
|
||||
//
|
||||
struct PerThreadDataStorage
|
||||
{
|
||||
BEAST_ALIGN(8)
|
||||
unsigned char bytes [sizeof (PerThreadData)];
|
||||
};
|
||||
|
||||
static Atomic <int> lastThreadId;
|
||||
|
||||
static ThreadLocalValue <PerThreadDataStorage> threadLocal;
|
||||
|
||||
static PerThreadData& getPerThreadData ();
|
||||
|
||||
struct Lists
|
||||
{
|
||||
GlobalThreadList allThreads;
|
||||
};
|
||||
|
||||
static CriticalSection& getGlobalMutex ();
|
||||
static Lists& getLists ();
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace beast
|
||||
|
||||
#endif
|
||||
@@ -1,478 +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 {
|
||||
namespace detail {
|
||||
|
||||
// Example:
|
||||
//
|
||||
// m_mutex[2] @ beast_deadlineTimer.cpp(25)
|
||||
//
|
||||
String detail::TrackedMutexBasics::createName (String name,
|
||||
char const* fileName, int lineNumber, int instanceNumber)
|
||||
{
|
||||
return name +
|
||||
((instanceNumber > 1) ?
|
||||
(String ("[") + String::fromNumber (instanceNumber) + "] (") : " (") +
|
||||
Debug::getFileNameFromPath (fileName) + "," +
|
||||
String::fromNumber (lineNumber) + ")";
|
||||
}
|
||||
|
||||
Atomic <int> TrackedMutexBasics::lastThreadId;
|
||||
|
||||
ThreadLocalValue <TrackedMutexBasics::PerThreadDataStorage> TrackedMutexBasics::threadLocal;
|
||||
|
||||
TrackedMutexBasics::PerThreadData::PerThreadData ()
|
||||
: id (++lastThreadId)
|
||||
{
|
||||
}
|
||||
|
||||
TrackedMutexBasics::PerThreadData& TrackedMutexBasics::getPerThreadData ()
|
||||
{
|
||||
PerThreadData& thread (*reinterpret_cast <PerThreadData*>(&threadLocal.get ()));
|
||||
|
||||
// Manually call the constructor with placement new if needed
|
||||
if (! thread.id)
|
||||
{
|
||||
new (&thread) PerThreadData ();
|
||||
bassert (thread.id != 0);
|
||||
}
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
CriticalSection& TrackedMutexBasics::getGlobalMutex ()
|
||||
{
|
||||
static CriticalSection mutex;
|
||||
return mutex;
|
||||
}
|
||||
|
||||
TrackedMutexBasics::Lists& TrackedMutexBasics::getLists ()
|
||||
{
|
||||
static Lists lists;
|
||||
return lists;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
} // detail
|
||||
|
||||
//==============================================================================
|
||||
|
||||
TrackedMutex::Record::Record (String mutexName,
|
||||
String threadName, String sourceLocation)
|
||||
: m_mutexName (mutexName)
|
||||
, m_threadName (threadName)
|
||||
, m_sourceLocation (sourceLocation)
|
||||
{
|
||||
}
|
||||
|
||||
TrackedMutex::Record::Record () noexcept
|
||||
{
|
||||
}
|
||||
|
||||
TrackedMutex::Record::Record (Record const& other) noexcept
|
||||
: m_mutexName (other.m_mutexName)
|
||||
, m_threadName (other.m_threadName)
|
||||
, m_sourceLocation (other.m_sourceLocation)
|
||||
{
|
||||
}
|
||||
|
||||
TrackedMutex::Record& TrackedMutex::Record::operator= (Record const& other) noexcept
|
||||
{
|
||||
m_mutexName = other.m_mutexName;
|
||||
m_threadName = other.m_threadName;
|
||||
m_sourceLocation = other.m_sourceLocation;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool TrackedMutex::Record::isNull () const noexcept
|
||||
{
|
||||
return m_mutexName == "";
|
||||
}
|
||||
|
||||
bool TrackedMutex::Record::isNotNull () const noexcept
|
||||
{
|
||||
return m_mutexName != "";
|
||||
}
|
||||
|
||||
TrackedMutex::Record::operator bool() const noexcept
|
||||
{
|
||||
return isNotNull ();
|
||||
}
|
||||
|
||||
String TrackedMutex::Record::getMutexName () const noexcept
|
||||
{
|
||||
return m_mutexName;
|
||||
}
|
||||
|
||||
String TrackedMutex::Record::getThreadName () const noexcept
|
||||
{
|
||||
return m_threadName;
|
||||
}
|
||||
|
||||
String TrackedMutex::Record::getSourceLocation () const noexcept
|
||||
{
|
||||
return m_sourceLocation;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TrackedMutex::Agent::Agent (detail::TrackedMutexBasics::PerThreadData* thread)
|
||||
: m_thread (thread)
|
||||
, m_threadName (thread->threadName)
|
||||
{
|
||||
}
|
||||
|
||||
TrackedMutex::Agent::Agent () noexcept
|
||||
: m_thread (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
TrackedMutex::Agent::Agent (Agent const& other) noexcept
|
||||
: m_thread (other.m_thread)
|
||||
, m_threadName (other.m_threadName)
|
||||
, m_blocked (other.m_blocked)
|
||||
{
|
||||
}
|
||||
|
||||
TrackedMutex::Agent& TrackedMutex::Agent::operator= (Agent const& other) noexcept
|
||||
{
|
||||
m_thread = other.m_thread;
|
||||
m_threadName = other.m_threadName;
|
||||
m_blocked = other.m_blocked;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool TrackedMutex::Agent::isNull () const noexcept
|
||||
{
|
||||
return m_thread == nullptr;
|
||||
}
|
||||
|
||||
bool TrackedMutex::Agent::isNotNull () const noexcept
|
||||
{
|
||||
return m_thread != nullptr;
|
||||
}
|
||||
|
||||
TrackedMutex::Agent::operator bool() const noexcept
|
||||
{
|
||||
return isNotNull ();
|
||||
}
|
||||
|
||||
String TrackedMutex::Agent::getThreadName () const noexcept
|
||||
{
|
||||
return m_threadName;
|
||||
}
|
||||
|
||||
TrackedMutex::Record TrackedMutex::Agent::getBlockedRecord () const noexcept
|
||||
{
|
||||
return m_blocked;
|
||||
}
|
||||
|
||||
bool TrackedMutex::Agent::getLockedList (Array <Record>& output)
|
||||
{
|
||||
bassert (isNotNull ());
|
||||
|
||||
output.clearQuick ();
|
||||
|
||||
typedef detail::TrackedMutexBasics::ThreadLockList ListType;
|
||||
|
||||
{
|
||||
CriticalSection::ScopedLockType lock (m_thread->mutex);
|
||||
|
||||
ListType const& list (m_thread->list);
|
||||
|
||||
output.ensureStorageAllocated (list.size ());
|
||||
|
||||
for (ListType::const_iterator iter = list.begin ();
|
||||
iter != list.end (); ++iter)
|
||||
{
|
||||
TrackedMutex const& mutex = *iter;
|
||||
{
|
||||
TrackedMutex::SharedState::ConstAccess state (mutex.m_state);
|
||||
output.add (state->owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output.size () > 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TrackedMutex::State::State ()
|
||||
: thread (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
TrackedMutex::TrackedMutex (String const& name) noexcept
|
||||
: m_name (name)
|
||||
, m_count (0)
|
||||
{
|
||||
}
|
||||
|
||||
String TrackedMutex::getName () const noexcept
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
TrackedMutex::Record TrackedMutex::getOwnerRecord () const noexcept
|
||||
{
|
||||
{
|
||||
SharedState::ConstAccess state (m_state);
|
||||
return state->owner;
|
||||
}
|
||||
}
|
||||
|
||||
TrackedMutex::Agent TrackedMutex::getOwnerAgent () const noexcept
|
||||
{
|
||||
{
|
||||
SharedState::ConstAccess state (m_state);
|
||||
if (state->thread != nullptr)
|
||||
return Agent (state->thread);
|
||||
}
|
||||
|
||||
return Agent ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TrackedMutex::generateGlobalBlockedReport (StringArray& report)
|
||||
{
|
||||
report.clear ();
|
||||
|
||||
{
|
||||
CriticalSection::ScopedLockType lock (
|
||||
detail::TrackedMutexBasics::getGlobalMutex ());
|
||||
|
||||
typedef detail::TrackedMutexBasics::GlobalThreadList ListType;
|
||||
|
||||
ListType const& list (detail::TrackedMutexBasics::getLists ().allThreads);
|
||||
|
||||
for (ListType::const_iterator iter = list.begin (); iter != list.end (); ++iter)
|
||||
{
|
||||
detail::TrackedMutexBasics::PerThreadData const* thread (
|
||||
&(*iter));
|
||||
|
||||
typedef detail::TrackedMutexBasics::ThreadLockList LockedList;
|
||||
LockedList const& owned (thread->list);
|
||||
|
||||
if (thread->blocked)
|
||||
{
|
||||
String s;
|
||||
s << thread->threadName << " blocked on " <<
|
||||
thread->blocked->getName () << " at " <<
|
||||
thread->sourceLocation;
|
||||
if (owned.size () > 0)
|
||||
s << " and owns these locks:";
|
||||
report.add (s);
|
||||
}
|
||||
else if (owned.size () > 0)
|
||||
{
|
||||
String s;
|
||||
s << thread->threadName << " owns these locks:";
|
||||
report.add (s);
|
||||
}
|
||||
|
||||
if (owned.size () > 0)
|
||||
{
|
||||
for (LockedList::const_iterator iter = owned.begin (); iter != owned.end (); ++iter)
|
||||
{
|
||||
String s;
|
||||
TrackedMutex const& mutex (*iter);
|
||||
TrackedMutex::SharedState::ConstAccess state (mutex.m_state);
|
||||
s << " " << mutex.getName () <<
|
||||
" from " << state->owner.getSourceLocation ();
|
||||
report.add (s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Called before we attempt to acquire the mutex.
|
||||
//
|
||||
void TrackedMutex::block (char const* fileName, int lineNumber) const noexcept
|
||||
{
|
||||
// Get calling thread data.
|
||||
detail::TrackedMutexBasics::PerThreadData& thread
|
||||
(detail::TrackedMutexBasics::getPerThreadData ());
|
||||
|
||||
++thread.refCount;
|
||||
|
||||
String const sourceLocation (makeSourceLocation (fileName, lineNumber));
|
||||
|
||||
{
|
||||
// Take a global lock.
|
||||
CriticalSection::ScopedLockType globalLock (
|
||||
detail::TrackedMutexBasics::getGlobalMutex ());
|
||||
|
||||
{
|
||||
// Take a thread lock.
|
||||
CriticalSection::ScopedLockType threadLock (thread.mutex);
|
||||
|
||||
// Set the thread's blocked record
|
||||
thread.blocked = this;
|
||||
thread.threadName = makeThreadName (thread);
|
||||
thread.sourceLocation = sourceLocation;
|
||||
|
||||
// Add this thread to threads list.
|
||||
if (thread.refCount == 1)
|
||||
detail::TrackedMutexBasics::getLists().allThreads.push_back (thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Called after we already have ownership of the mutex
|
||||
//
|
||||
void TrackedMutex::acquired (char const* fileName, int lineNumber) const noexcept
|
||||
{
|
||||
// Retrieve the per-thread data for the calling thread.
|
||||
detail::TrackedMutexBasics::PerThreadData& thread
|
||||
(detail::TrackedMutexBasics::getPerThreadData ());
|
||||
|
||||
// If this goes off it means block() wasn't called.
|
||||
bassert (thread.refCount > 0);
|
||||
|
||||
++m_count;
|
||||
|
||||
// Take ownership on the first count.
|
||||
if (m_count == 1)
|
||||
{
|
||||
// Thread is a new owner of the mutex.
|
||||
String const sourceLocation (makeSourceLocation (fileName, lineNumber));
|
||||
String const threadName (makeThreadName (thread));
|
||||
|
||||
{
|
||||
// Take a global lock.
|
||||
CriticalSection::ScopedLockType globalLock (
|
||||
detail::TrackedMutexBasics::getGlobalMutex ());
|
||||
|
||||
{
|
||||
// Take a state lock.
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
// Set the mutex ownership record
|
||||
state->owner = Record (getName (), threadName, sourceLocation);
|
||||
state->thread = &thread;
|
||||
|
||||
{
|
||||
// Take a thread lock.
|
||||
CriticalSection::ScopedLockType threadLock (thread.mutex);
|
||||
|
||||
// Add the mutex to the thread's list.
|
||||
thread.list.push_back (const_cast <TrackedMutex&>(*this));
|
||||
|
||||
// Unblock the thread record.
|
||||
thread.blocked = nullptr;
|
||||
thread.sourceLocation = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Thread already had ownership of the mutex.
|
||||
bassert (SharedState::ConstUnlockedAccess (m_state)->thread == &thread);
|
||||
|
||||
// If this goes off it means we counted wrong.
|
||||
bassert (thread.refCount >= m_count);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TrackedMutex::release () const noexcept
|
||||
{
|
||||
// If this goes off it means we don't own the mutex!
|
||||
bassert (m_count > 0);
|
||||
|
||||
// Retrieve the per-thread data for the calling thread.
|
||||
detail::TrackedMutexBasics::PerThreadData& thread
|
||||
(detail::TrackedMutexBasics::getPerThreadData ());
|
||||
|
||||
// If this goes off it means we counted wrong.
|
||||
bassert (thread.refCount >= m_count);
|
||||
|
||||
--m_count;
|
||||
--thread.refCount;
|
||||
|
||||
// Give up ownership when the count drops to zero.
|
||||
if (m_count == 0)
|
||||
{
|
||||
// Take the global mutex
|
||||
CriticalSection::ScopedLockType globalLock (
|
||||
detail::TrackedMutexBasics::getGlobalMutex ());
|
||||
|
||||
{
|
||||
// Take the mutex' state lock
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
// Clear the mutex ownership record
|
||||
state->owner = Record ();
|
||||
state->thread = nullptr;
|
||||
|
||||
{
|
||||
// Take the thread mutex
|
||||
CriticalSection::ScopedLockType threadLock (thread.mutex);
|
||||
|
||||
// Remove this mutex from the list of the thread's owned locks.
|
||||
thread.list.erase (thread.list.iterator_to (
|
||||
const_cast <TrackedMutex&>(*this)));
|
||||
|
||||
// Remove this thread from the threads list.
|
||||
if (thread.refCount == 0)
|
||||
{
|
||||
typedef detail::TrackedMutexBasics::GlobalThreadList ListType;
|
||||
ListType& list (detail::TrackedMutexBasics::getLists().allThreads);
|
||||
list.erase (list.iterator_to (thread));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
String TrackedMutex::makeThreadName (
|
||||
detail::TrackedMutexBasics::PerThreadData const& thread) noexcept
|
||||
{
|
||||
String threadName;
|
||||
Thread const* const currentThread (Thread::getCurrentThread ());
|
||||
if (currentThread != nullptr)
|
||||
threadName = currentThread->getThreadName ();
|
||||
threadName = threadName + "[" + String::fromNumber (thread.id) + "]";
|
||||
return threadName;
|
||||
}
|
||||
|
||||
String TrackedMutex::makeSourceLocation (char const* fileName, int lineNumber) noexcept
|
||||
{
|
||||
String const sourceLocation (Debug::getFileNameFromPath (fileName, 1) + "(" +
|
||||
String::fromNumber (lineNumber) + ")");
|
||||
|
||||
return sourceLocation;
|
||||
}
|
||||
|
||||
} // beast
|
||||
@@ -1,173 +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_CORE_THREAD_IMPL_TRACKEDMUTEX_H_INCLUDED
|
||||
#define BEAST_CORE_THREAD_IMPL_TRACKEDMUTEX_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
/** Common types and member functions for a TrackedMutex */
|
||||
class TrackedMutex
|
||||
: public detail::TrackedMutexBasics::ThreadLockList::Node
|
||||
{
|
||||
public:
|
||||
class Agent;
|
||||
class Location;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** A triplet identifying a mutex, a thread, and source code location.
|
||||
*/
|
||||
class Record
|
||||
{
|
||||
public:
|
||||
Record () noexcept;
|
||||
Record (Record const& other) noexcept;
|
||||
Record& operator= (Record const& other) noexcept;
|
||||
|
||||
bool isNull () const noexcept;
|
||||
bool isNotNull () const noexcept;
|
||||
explicit operator bool() const noexcept;
|
||||
|
||||
/** Returns the name of the mutex.
|
||||
Since the Mutex may not exist after the Record record is
|
||||
created, we only provide a String, which is always valid.
|
||||
*/
|
||||
String getMutexName () const noexcept;
|
||||
|
||||
/** Returns the name of the associated thread.
|
||||
The name is generated at the time the record is created,
|
||||
and might have changed since that time, or may no longer exist.
|
||||
*/
|
||||
String getThreadName () const noexcept;
|
||||
|
||||
/** Returns the position within the source code.
|
||||
This will either be the place a lock was acquired, or the place
|
||||
where a thread is trying to acquire a lock. The vaue is only
|
||||
meaningful at the time the Record is created. Since then, the
|
||||
thread may have changed its state.
|
||||
*/
|
||||
String getSourceLocation () const noexcept;
|
||||
|
||||
private:
|
||||
friend class TrackedMutex;
|
||||
|
||||
Record (String mutexName, String threadName, String sourceLocation);
|
||||
|
||||
String m_mutexName;
|
||||
String m_threadName;
|
||||
String m_sourceLocation;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Describes a thread that can acquire mutexes. */
|
||||
class Agent
|
||||
{
|
||||
public:
|
||||
Agent () noexcept;
|
||||
Agent (Agent const& other) noexcept;
|
||||
Agent& operator= (Agent const& other) noexcept;
|
||||
|
||||
bool isNull () const noexcept;
|
||||
bool isNotNull () const noexcept;
|
||||
explicit operator bool() const noexcept;
|
||||
|
||||
/** Returns the name of the thread.
|
||||
The name is generated at the time the Agent record is created,
|
||||
and might have changed since that time.
|
||||
*/
|
||||
String getThreadName () const noexcept;
|
||||
|
||||
/** Returns a Record indicating where the thread is blocked on a mutex.
|
||||
If the thread is not blocked, a null Record is returned.
|
||||
The value is only meaningful at the moment of the call as conditions
|
||||
can change.
|
||||
*/
|
||||
Record getBlockedRecord () const noexcept;
|
||||
|
||||
/** Retrieve a list of other locks that this thread holds.
|
||||
Each lock is represented by a Location indicating the place
|
||||
The value is only meaningful at the moment of the call as conditions
|
||||
can change.
|
||||
@return `true` if the list is not empty.
|
||||
*/
|
||||
bool getLockedList (Array <Record>& list);
|
||||
|
||||
private:
|
||||
friend class TrackedMutex;
|
||||
explicit Agent (detail::TrackedMutexBasics::PerThreadData* thread);
|
||||
|
||||
detail::TrackedMutexBasics::PerThreadData* m_thread;
|
||||
String m_threadName;
|
||||
Record m_blocked;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Retrieve the name of this mutex.
|
||||
Thread safety: May be called from any thread.
|
||||
*/
|
||||
String getName () const noexcept;
|
||||
|
||||
/** Retrieve a Record for the current owner.
|
||||
It is only valid at the one instant in time, as the person holding it
|
||||
might have released it shortly afterwards. If there is no owner,
|
||||
a null Record is returned.
|
||||
*/
|
||||
Record getOwnerRecord () const noexcept;
|
||||
|
||||
/** Retrieve the Agent for the current owner.
|
||||
It is only valid at the one instant in time, as the person holding it
|
||||
might have released it shortly afterwards. If there is no owner,
|
||||
a null Agent is returned.
|
||||
*/
|
||||
Agent getOwnerAgent () const noexcept;
|
||||
|
||||
/** Produce a report on the state of all blocked threads. */
|
||||
static void generateGlobalBlockedReport (StringArray& report);
|
||||
|
||||
protected:
|
||||
static String makeThreadName (detail::TrackedMutexBasics::PerThreadData const&) noexcept;
|
||||
static String makeSourceLocation (char const* fileName, int lineNumber) noexcept;
|
||||
|
||||
TrackedMutex (String const& name) noexcept;
|
||||
void block (char const* fileName, int lineNumber) const noexcept;
|
||||
void acquired (char const* fileName, int lineNumber) const noexcept;
|
||||
void release () const noexcept;
|
||||
|
||||
private:
|
||||
struct State
|
||||
{
|
||||
State ();
|
||||
Record owner;
|
||||
detail::TrackedMutexBasics::PerThreadData* thread;
|
||||
};
|
||||
|
||||
typedef SharedData <State> SharedState;
|
||||
|
||||
String const m_name;
|
||||
int mutable m_count;
|
||||
SharedState mutable m_state;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
|
||||
#endif
|
||||
@@ -1,100 +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_CORE_THREAD_TRACKEDMUTEXTYPE_H_INCLUDED
|
||||
#define BEAST_CORE_THREAD_TRACKEDMUTEXTYPE_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
/** A template that gives a Mutex diagnostic tracking capabilities. */
|
||||
template <typename Mutex>
|
||||
class TrackedMutexType
|
||||
: public TrackedMutex
|
||||
{
|
||||
public:
|
||||
/** The type of ScopedLock to use with this TrackedMutexType object. */
|
||||
typedef detail::TrackedScopedLock <TrackedMutexType <Mutex> > ScopedLockType;
|
||||
|
||||
/** The type of ScopedTrylock to use with this TrackedMutexType object. */
|
||||
typedef detail::TrackedScopedTryLock <TrackedMutexType <Mutex> > ScopedTryLockType;
|
||||
|
||||
/** The type of ScopedUnlock to use with this TrackedMutexType object. */
|
||||
typedef detail::TrackedScopedUnlock <TrackedMutexType <Mutex> > ScopedUnlockType;
|
||||
|
||||
/** Construct a mutex, keyed to a particular class.
|
||||
Just pass 'this' for owner and give it the name of the data member
|
||||
of your class.
|
||||
*/
|
||||
template <typename Object>
|
||||
TrackedMutexType (Object const* object,
|
||||
String name,
|
||||
char const* fileName,
|
||||
int lineNumber)
|
||||
: TrackedMutex (detail::TrackedMutexBasics::createName <Object> (
|
||||
name, fileName, lineNumber))
|
||||
{
|
||||
}
|
||||
|
||||
/** Construct a mutex, without a class association.
|
||||
These will all get numbered together as a group.
|
||||
*/
|
||||
TrackedMutexType (String name, char const* fileName, int lineNumber)
|
||||
: TrackedMutex (detail::TrackedMutexBasics::createName (name,
|
||||
fileName, lineNumber))
|
||||
{
|
||||
}
|
||||
|
||||
~TrackedMutexType () noexcept
|
||||
{
|
||||
}
|
||||
|
||||
inline void lock (char const* fileName, int lineNumber) const noexcept
|
||||
{
|
||||
block (fileName, lineNumber);
|
||||
MutexTraits <Mutex>::lock (m_mutex);
|
||||
acquired (fileName, lineNumber);
|
||||
}
|
||||
|
||||
inline void unlock () const noexcept
|
||||
{
|
||||
release ();
|
||||
MutexTraits <Mutex>::unlock (m_mutex);
|
||||
}
|
||||
|
||||
// VFALCO NOTE: We could use enable_if here...
|
||||
inline bool try_lock (char const* fileName, int lineNumber) const noexcept
|
||||
{
|
||||
bool const success = MutexTraits <Mutex>::try_lock (m_mutex);
|
||||
if (success)
|
||||
{
|
||||
// Hack, call block to prevent counts from going wrong.
|
||||
block (fileName, lineNumber);
|
||||
acquired (fileName, lineNumber);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
private:
|
||||
Mutex const m_mutex;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
|
||||
#endif
|
||||
@@ -1,87 +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_CORE_THREAD_IMPL_UNTRACKEDMUTEX_H_INCLUDED
|
||||
#define BEAST_CORE_THREAD_IMPL_UNTRACKEDMUTEX_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
/** A drop-in replacement for TrackedMutex without the tracking.
|
||||
*/
|
||||
template <typename Mutex>
|
||||
class UntrackedMutexType
|
||||
: public Uncopyable
|
||||
{
|
||||
public:
|
||||
typedef detail::UntrackedScopedLock <UntrackedMutexType <Mutex> > ScopedLockType;
|
||||
typedef detail::UntrackedScopedTryLock <UntrackedMutexType <Mutex> > ScopedTryLockType;
|
||||
typedef detail::UntrackedScopedUnlock <UntrackedMutexType <Mutex> > ScopedUnlockType;
|
||||
|
||||
template <typename Object>
|
||||
inline UntrackedMutexType (Object const*, String name, char const*, int) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
inline UntrackedMutexType (String, char const*, int) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
inline UntrackedMutexType () noexcept
|
||||
{
|
||||
}
|
||||
|
||||
inline ~UntrackedMutexType () noexcept
|
||||
{
|
||||
}
|
||||
|
||||
inline void lock () const noexcept
|
||||
{
|
||||
MutexTraits <Mutex>::lock (m_mutex);
|
||||
}
|
||||
|
||||
inline void lock (char const*, int) const noexcept
|
||||
{
|
||||
MutexTraits <Mutex>::lock (m_mutex);
|
||||
}
|
||||
|
||||
inline void unlock () const noexcept
|
||||
{
|
||||
MutexTraits <Mutex>::unlock (m_mutex);
|
||||
}
|
||||
|
||||
// VFALCO NOTE: We could use enable_if here...
|
||||
|
||||
inline bool try_lock () const noexcept
|
||||
{
|
||||
return MutexTraits <Mutex>::try_lock (m_mutex);
|
||||
}
|
||||
|
||||
inline bool try_lock (char const*, int) const noexcept
|
||||
{
|
||||
return MutexTraits <Mutex>::try_lock (m_mutex);
|
||||
}
|
||||
|
||||
private:
|
||||
Mutex mutable m_mutex;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
|
||||
#endif
|
||||
@@ -1,97 +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
|
||||
{
|
||||
|
||||
ChildProcess::ChildProcess() {}
|
||||
ChildProcess::~ChildProcess() {}
|
||||
|
||||
bool ChildProcess::waitForProcessToFinish (const int timeoutMs) const
|
||||
{
|
||||
const uint32 timeoutTime = Time::getMillisecondCounter() + (uint32) timeoutMs;
|
||||
|
||||
do
|
||||
{
|
||||
if (! isRunning())
|
||||
return true;
|
||||
}
|
||||
while (timeoutMs < 0 || Time::getMillisecondCounter() < timeoutTime);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
String ChildProcess::readAllProcessOutput()
|
||||
{
|
||||
MemoryOutputStream result;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char buffer [512];
|
||||
const int num = readProcessOutput (buffer, sizeof (buffer));
|
||||
|
||||
if (num <= 0)
|
||||
break;
|
||||
|
||||
result.write (buffer, (size_t) num);
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
class ChildProcess_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
void run()
|
||||
{
|
||||
#if BEAST_WINDOWS || BEAST_MAC || BEAST_LINUX
|
||||
ChildProcess p;
|
||||
|
||||
#if BEAST_WINDOWS
|
||||
expect (p.start ("tasklist"));
|
||||
#else
|
||||
expect (p.start ("ls /"));
|
||||
#endif
|
||||
|
||||
if (! p.waitForProcessToFinish (10 * 1000))
|
||||
{
|
||||
if (p.kill ())
|
||||
p.waitForProcessToFinish (-1);
|
||||
}
|
||||
|
||||
//String output (p.readAllProcessOutput());
|
||||
//expect (output.isNotEmpty());
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
// VFALCO NOTE I had to disable this test because it was leaving
|
||||
// behind a zombie process and making other unit tests fail.
|
||||
// It doesnt happen with a debugger attached, or if the
|
||||
// unit test is run individually.
|
||||
//
|
||||
BEAST_DEFINE_TESTSUITE_MANUAL(ChildProcess,beast_core,beast);
|
||||
|
||||
} // beast
|
||||
@@ -1,101 +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_CHILDPROCESS_H_INCLUDED
|
||||
#define BEAST_CHILDPROCESS_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Launches and monitors a child process.
|
||||
|
||||
This class lets you launch an executable, and read its output. You can also
|
||||
use it to check whether the child process has finished.
|
||||
*/
|
||||
class BEAST_API ChildProcess : LeakChecked <ChildProcess>, public Uncopyable
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a process object.
|
||||
To actually launch the process, use start().
|
||||
*/
|
||||
ChildProcess();
|
||||
|
||||
/** Destructor.
|
||||
Note that deleting this object won't terminate the child process.
|
||||
*/
|
||||
~ChildProcess();
|
||||
|
||||
/** Attempts to launch a child process command.
|
||||
|
||||
The command should be the name of the executable file, followed by any arguments
|
||||
that are required.
|
||||
If the process has already been launched, this will launch it again. If a problem
|
||||
occurs, the method will return false.
|
||||
*/
|
||||
bool start (const String& command);
|
||||
|
||||
/** Attempts to launch a child process command.
|
||||
|
||||
The first argument should be the name of the executable file, followed by any other
|
||||
arguments that are needed.
|
||||
If the process has already been launched, this will launch it again. If a problem
|
||||
occurs, the method will return false.
|
||||
*/
|
||||
bool start (const StringArray& arguments);
|
||||
|
||||
/** Returns true if the child process is alive. */
|
||||
bool isRunning() const;
|
||||
|
||||
/** Attempts to read some output from the child process.
|
||||
This will attempt to read up to the given number of bytes of data from the
|
||||
process. It returns the number of bytes that were actually read.
|
||||
*/
|
||||
int readProcessOutput (void* destBuffer, int numBytesToRead);
|
||||
|
||||
/** Blocks until the process has finished, and then returns its complete output
|
||||
as a string.
|
||||
*/
|
||||
String readAllProcessOutput();
|
||||
|
||||
/** Blocks until the process is no longer running. */
|
||||
bool waitForProcessToFinish (int timeoutMs) const;
|
||||
|
||||
/** Attempts to kill the child process.
|
||||
Returns true if it succeeded. Trying to read from the process after calling this may
|
||||
result in undefined behaviour.
|
||||
*/
|
||||
bool kill();
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class ActiveProcess;
|
||||
friend class ScopedPointer<ActiveProcess>;
|
||||
ScopedPointer<ActiveProcess> activeProcess;
|
||||
};
|
||||
|
||||
} // namespace beast
|
||||
|
||||
#endif // BEAST_CHILDPROCESS_H_INCLUDED
|
||||
@@ -24,8 +24,9 @@
|
||||
#ifndef BEAST_CRITICALSECTION_H_INCLUDED
|
||||
#define BEAST_CRITICALSECTION_H_INCLUDED
|
||||
|
||||
namespace beast
|
||||
{
|
||||
#include "ScopedLock.h"
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
@@ -35,9 +36,9 @@ namespace beast
|
||||
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, ReadWriteLock, Thread, InterProcessLock
|
||||
@see ScopedLock, ScopedTryLock, ScopedUnlock, SpinLock, Thread
|
||||
*/
|
||||
class BEAST_API CriticalSection : public Uncopyable
|
||||
class CriticalSection : public Uncopyable
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
@@ -117,9 +118,9 @@ private:
|
||||
// a block of memory here that's big enough to be used internally as a windows
|
||||
// CRITICAL_SECTION structure.
|
||||
#if BEAST_64BIT
|
||||
uint8 section[44];
|
||||
std::uint8_t section[44];
|
||||
#else
|
||||
uint8 section[24];
|
||||
std::uint8_t section[24];
|
||||
#endif
|
||||
#else
|
||||
mutable pthread_mutex_t mutex;
|
||||
@@ -134,9 +135,9 @@ private:
|
||||
This is currently used by some templated classes, and most compilers should
|
||||
manage to optimise it out of existence.
|
||||
|
||||
@see CriticalSection, Array, OwnedArray, SharedObjectArray
|
||||
@see CriticalSection, Array, SharedObjectArray
|
||||
*/
|
||||
class BEAST_API DummyCriticalSection : public Uncopyable
|
||||
class DummyCriticalSection : public Uncopyable
|
||||
{
|
||||
public:
|
||||
inline DummyCriticalSection() noexcept {}
|
||||
@@ -255,6 +256,6 @@ typedef CriticalSection::ScopedUnlockType ScopedUnlock;
|
||||
*/
|
||||
typedef CriticalSection::ScopedTryLockType ScopedTryLock;
|
||||
|
||||
} // namespace beast
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_CRITICALSECTION_H_INCLUDED
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user