text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

IPAddress::IPAddress (bool IPv6) noexcept : isIPv6 (IPv6)
{
    for (int i = 0; i < 16; ++i)
        address[i] = 0;
}

IPAddress::IPAddress (const uint8 bytes[], bool IPv6) noexcept : isIPv6 (IPv6)
{
    for (int i = 0; i < (isIPv6 ? 16 : 4); ++i)
        address[i] = bytes[i];

    if (! isIPv6)
        zeroUnusedBytes();
}

IPAddress::IPAddress (const uint16 bytes[8]) noexcept : isIPv6 (true)
{
    ByteUnion temp;

    for (int i = 0; i < 8; ++i)
    {
        temp.combined = bytes[i];

        address[i * 2]     = temp.split[0];
        address[i * 2 + 1] = temp.split[1];
    }
}

IPAddress::IPAddress (uint8 a0, uint8 a1, uint8 a2, uint8 a3) noexcept : isIPv6 (false)
{
    address[0] = a0;  address[1] = a1;
    address[2] = a2;  address[3] = a3;

    zeroUnusedBytes();
}

IPAddress::IPAddress (uint16 a1, uint16 a2, uint16 a3, uint16 a4,
                      uint16 a5, uint16 a6, uint16 a7, uint16 a8) noexcept : isIPv6 (true)

{
    uint16 array[8] = { a1, a2, a3, a4, a5, a6, a7, a8 };

    ByteUnion temp;

    for (int i = 0; i < 8; ++i)
    {
        temp.combined = array[i];
        address[i * 2]     = temp.split[0];
        address[i * 2 + 1] = temp.split[1];
    }
}

IPAddress::IPAddress (uint32 n) noexcept : isIPv6 (false)
{
    address[0] = (n >> 24);
    address[1] = (n >> 16) & 255;
    address[2] = (n >> 8) & 255;
    address[3] = (n & 255);

    zeroUnusedBytes();
}

IPAddress::IPAddress (const String& adr)
{
    isIPv6 = adr.contains (":");

    if (! isIPv6)
    {
        StringArray tokens;
        tokens.addTokens (adr, ".", String());

        for (int i = 0; i < 4; ++i)
            address[i] = (uint8) tokens[i].getIntValue();
    }
    else
    {
        StringArray tokens;
        tokens.addTokens (adr.removeCharacters ("[]"), ":", String());

        if (tokens.contains (StringRef())) // if :: shorthand has been used
        {
            int idx = tokens.indexOf (StringRef());
            tokens.set (idx, "0");

            while (tokens.size() < 8)
                tokens.insert (idx, "0");
        }

        for (int i = 0; i < 8; ++i)
        {
            ByteUnion temp;
            temp.combined = (uint16) CharacterFunctions::HexParser<int>::parse (tokens[i].getCharPointer());

            address[i * 2]     = temp.split[0];
            address[i * 2 + 1] = temp.split[1];
        }
    }
}

String IPAddress::toString() const
{
    if (! isIPv6)
    {
        String s ((int) address[0]);

        for (int i = 1; i < 4; ++i)
            s << '.' << (int) address[i];

        return s;
    }

    String addressString;
    ByteUnion temp;

    temp.split[0] = address[0];
    temp.split[1] = address[1];

    addressString = String (String::toHexString (temp.combined));

    for (int i = 1; i < 8; ++i)
    {
        temp.split[0] = address[i * 2];
        temp.split[1] = address[i * 2 + 1];

        addressString << ':' << String (String::toHexString (temp.combined));
    }

    return getFormattedAddress (addressString);
}

IPAddress IPAddress::any (bool IPv6) noexcept           { return IPAddress (IPv6); }
IPAddress IPAddress::broadcast() noexcept               { return IPAddress (255, 255, 255, 255); }
IPAddress IPAddress::local (bool IPv6) noexcept         { return IPv6 ? IPAddress (0, 0, 0, 0, 0, 0, 0, 1)
                                                                      : IPAddress (127, 0, 0, 1); }

String IPAddress::getFormattedAddress (const String& unformattedAddress)
{
    jassert (unformattedAddress.contains (":") && ! unformattedAddress.contains ("::")); // needs to be an unformatted IPv6 address!

    String portString = unformattedAddress.fromFirstOccurrenceOf ("]", false, true);
    String addressString = unformattedAddress.dropLastCharacters (portString.length()).removeCharacters ("[]");

    StringArray tokens;
    tokens.addTokens (addressString, ":", String());

    int numZeros = 0;
    int numZerosTemp = 0;
    bool isFirst = false;
    bool isLast = false;

    for (int i = 0; i < tokens.size(); ++i)
    {
        String t = tokens.getReference (i);

        if (t.getHexValue32() == 0x0000)
        {
            ++numZeros;

            if (i == 0)
                isFirst = true;
            else if (i == tokens.size() - 1 && numZeros > numZerosTemp)
                isLast = true;

            if (t.length() > 1)
                addressString = addressString.replace (String::repeatedString ("0", t.length()), "0");

            if (isFirst && numZerosTemp != 0 && numZeros > numZerosTemp)
                isFirst = false;
        }
        else
        {
            addressString = addressString.replace (t, t.trimCharactersAtStart ("0").toLowerCase());

            if (numZeros > 0)
            {
                if (numZeros > numZerosTemp)
                    numZerosTemp = numZeros;

                numZeros = 0;
            }
        }
    }

    if (numZerosTemp > numZeros)
        numZeros = numZerosTemp;

    if (numZeros > 1)
    {
        if (numZeros == tokens.size())
            addressString = "::,";
        else
        {
            String zeroString = isFirst ? String ("0") + String::repeatedString (":0", numZeros - 1)
                                        : String::repeatedString (":0", numZeros);

            addressString = addressString.replaceFirstOccurrenceOf (zeroString, ":");

            if (isLast)
                addressString += String (":");
        }
    }

    if (portString.isNotEmpty())
        addressString = String ("[") + addressString + String ("]") + portString;

    return addressString;
}

bool IPAddress::operator== (const IPAddress& other) const noexcept
{
    for (int i = 0; i < (isIPv6 ? 16 : 4); ++i)
        if (address[i] != other.address[i])
            return false;

    return true;

}

bool IPAddress::operator!= (const IPAddress& other) const noexcept
{
    return ! operator== (other);
}

#if (! JUCE_WINDOWS) && (! JUCE_ANDROID)
static void addAddress (const sockaddr_in* addr_in, Array<IPAddress>& result)
{
    in_addr_t addr = addr_in->sin_addr.s_addr;

    if (addr != INADDR_NONE)
        result.addIfNotAlreadyThere (IPAddress (ntohl (addr)));
}

static void addAddress (const sockaddr_in6* addr_in, Array<IPAddress>& result)
{
    in6_addr addr = addr_in->sin6_addr;

    typedef union
    {
        uint16 combined;
        uint8 split[2];
    } ByteUnion;

    ByteUnion temp;
    uint16 arr[8];

    for (int i = 0; i < 8; ++i) // Swap bytes from network to host order
    {
        temp.split[0] = addr.s6_addr[i * 2 + 1];
        temp.split[1] = addr.s6_addr[i * 2];

        arr[i] = temp.combined;
    }

    IPAddress ip (arr);
    result.addIfNotAlreadyThere (ip);
}

void IPAddress::findAllAddresses (Array<IPAddress>& result, bool includeIPv6)
{
    struct ifaddrs *ifaddr, *ifa;

    if (getifaddrs (&ifaddr) == -1)
        return;

    for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next)
    {
        if (ifa->ifa_addr == nullptr)
            continue;

        if      (ifa->ifa_addr->sa_family == AF_INET)                 addAddress ((const sockaddr_in*)  ifa->ifa_addr, result);
        else if (ifa->ifa_addr->sa_family == AF_INET6 && includeIPv6) addAddress ((const sockaddr_in6*) ifa->ifa_addr, result);
    }

    freeifaddrs (ifaddr);
}
#endif

} // namespace juce


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

//==============================================================================
/**
    Represents a MAC network card adapter address ID.
*/
class JUCE_API  MACAddress  final
{
public:
    //==============================================================================
    /** Populates a list of the MAC addresses of all the available network cards. */
    static void findAllAddresses (Array<MACAddress>& results);

    //==============================================================================
    /** Creates a null address (00-00-00-00-00-00). */
    MACAddress() noexcept;

    /** Creates a copy of another address. */
    MACAddress (const MACAddress&) noexcept;

    /** Creates a copy of another address. */
    MACAddress& operator= (const MACAddress&) noexcept;

    /** Creates an address from 6 bytes. */
    explicit MACAddress (const uint8 bytes[6]) noexcept;

    /** Creates an address from a hex string.
        If the string isn't a 6-byte hex value, this will just default-initialise
        the object.
    */
    explicit MACAddress (StringRef address);

    /** Returns a pointer to the 6 bytes that make up this address. */
    const uint8* getBytes() const noexcept        { return address; }

    /** Returns a dash-separated string in the form "11-22-33-44-55-66" */
    String toString() const;

    /** Returns a hex string of this address, using a custom separator between each byte. */
    String toString (StringRef separator) const;

    /** Returns the address in the lower 6 bytes of an int64.

        This uses a little-endian arrangement, with the first byte of the address being
        stored in the least-significant byte of the result value.
    */
    int64 toInt64() const noexcept;

    /** Returns true if this address is null (00-00-00-00-00-00). */
    bool isNull() const noexcept;

    bool operator== (const MACAddress&) const noexcept;
    bool operator!= (const MACAddress&) const noexcept;

    //==============================================================================
private:
    uint8 address[6];
};

} // namespace juce

repo_name: fedden/RenderMan

mime_type: text/x-c++


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

WebInputStream::WebInputStream (const URL& url, const bool usePost)
    : pimpl (new Pimpl (*this, url, usePost)), hasCalledConnect (false)
{
}

WebInputStream::~WebInputStream()
{
    delete pimpl;
}

WebInputStream& WebInputStream::withExtraHeaders (const String& extra)         { pimpl->withExtraHeaders (extra);       return *this; }
WebInputStream& WebInputStream::withCustomRequestCommand (const String& cmd)   { pimpl->withCustomRequestCommand(cmd);  return *this; }
WebInputStream& WebInputStream::withConnectionTimeout (int t)                  { pimpl->withConnectionTimeout (t);      return *this; }
WebInputStream& WebInputStream::withNumRedirectsToFollow (int num)             { pimpl->withNumRedirectsToFollow (num); return *this; }
StringPairArray WebInputStream::getRequestHeaders() const                      { return pimpl->getRequestHeaders(); }
StringPairArray WebInputStream::getResponseHeaders()                           { connect (nullptr); return pimpl->getResponseHeaders(); }
bool WebInputStream::isError() const                                           { return pimpl->isError(); }
void WebInputStream::cancel()                                                  { pimpl->cancel(); }
bool WebInputStream::isExhausted()                                             { return pimpl->isExhausted(); }
int64 WebInputStream::getPosition()                                            { return pimpl->getPosition(); }
int64 WebInputStream::getTotalLength()                                         { connect (nullptr); return pimpl->getTotalLength(); }
int WebInputStream::read (void* buffer, int bytes)                             { connect (nullptr); return pimpl->read (buffer, bytes); }
bool WebInputStream::setPosition (int64 pos)                                   { return pimpl->setPosition (pos); }
int WebInputStream::getStatusCode()                                            { connect (nullptr); return pimpl->getStatusCode(); }

bool WebInputStream::connect (Listener* listener)
{
    if (hasCalledConnect)
        return ! isError();

    hasCalledConnect = true;
    return pimpl->connect (listener);
}

StringPairArray WebInputStream::parseHttpHeaders (const String& headerData)
{
    StringPairArray headerPairs;
    StringArray headerLines = StringArray::fromLines (headerData);

    // ignore the first line as this is the status line
    for (int i = 1; i < headerLines.size(); ++i)
    {
        const String& headersEntry = headerLines[i];

        if (headersEntry.isNotEmpty())
        {
            const String key   (headersEntry.upToFirstOccurrenceOf (": ", false, false));
            const String value (headersEntry.fromFirstOccurrenceOf (": ", false, false));
            const String previousValue (headerPairs [key]);
            headerPairs.set (key, previousValue.isEmpty() ? value : (previousValue + "," + value));
        }
    }

    return headerPairs;
}

void WebInputStream::createHeadersAndPostData (const URL& aURL, String& headers, MemoryBlock& data)
{
    aURL.createHeadersAndPostData (headers, data);
}

} // namespace juce


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

//==============================================================================
/**
    Represents an IP address.
*/
class JUCE_API  IPAddress  final
{
public:
    //==============================================================================
    /** Populates a list of all the IP addresses that this machine is using. */
    static void findAllAddresses (Array<IPAddress>& results, bool includeIPv6 = false);

    //==============================================================================
    /** Creates a null address - 0.0.0.0 (IPv4) or ::, (IPv6)
        @param IPv6 if true indicates that this is an IPv6 address
    */
    IPAddress (bool IPv6 = false) noexcept;

    /** Creates an IPv4 or IPv6 address by reading 4 or 16 bytes from an array.
        @param bytes The array containing the bytes to read.
        @param IPv6 if true indicates that 16 bytes should be read instead of 4.
    */
    explicit IPAddress (const uint8 bytes[], bool IPv6 = false) noexcept;

    /** Creates an IPv6 address from an array of 8 16-bit integers
        @param bytes The array containing the bytes to read.
    */
    explicit IPAddress (const uint16 bytes[8]) noexcept;

    /** Creates an IPv4 address from 4 bytes. */
    IPAddress (uint8 address1, uint8 address2, uint8 address3, uint8 address4) noexcept;

    /** Creates an IPv6 address from 8 16-bit integers */
    IPAddress (uint16 address1, uint16 address2, uint16 address3, uint16 address4,
               uint16 address5, uint16 address6, uint16 address7, uint16 address8) noexcept;

    /** Creates an IPv4 address from a packed 32-bit integer, where the
        MSB is the first number in the address, and the LSB is the last.
    */
    explicit IPAddress (uint32 asNativeEndian32Bit) noexcept;

    /** Parses a string IP address of the form "1.2.3.4" (IPv4) or "1:2:3:4:5:6:7:8" (IPv6). */
    explicit IPAddress (const String& address);

    /** Returns a dot- or colon-separated string in the form "1.2.3.4" (IPv4) or "1:2:3:4:5:6:7:8" (IPv6). */
    String toString() const;

    /** Returns an IPv4 or IPv6 address meaning "any", equivalent to 0.0.0.0 (IPv4) or ::, (IPv6)  */
    static IPAddress any (bool IPv6 = false) noexcept;

    /** Returns an IPv4 address meaning "broadcast" (255.255.255.255) */
    static IPAddress broadcast() noexcept;

    /** Returns an IPv4 or IPv6 address meaning "localhost", equivalent to 127.0.0.1 (IPv4) or ::1 (IPv6) */
    static IPAddress local (bool IPv6 = false) noexcept;

    /** Returns a formatted version of the provided IPv6 address conforming to RFC 5952 with leading zeros suppressed,
        lower case characters, and double-colon notation used to represent contiguous 16-bit fields of zeros.

        @param unformattedAddress the IPv6 address to be formatted
    */
    static String getFormattedAddress (const String& unformattedAddress);

    bool operator== (const IPAddress& other) const noexcept;
    bool operator!= (const IPAddress& other) const noexcept;

    /** The elements of the IP address. */
    uint8 address[16];

    bool isIPv6;

private:
    /** Union used to split a 16-bit unsigned integer into 2 8-bit unsigned integers or vice-versa */
    typedef union
    {
        uint16 combined;
        uint8 split[2];
    } ByteUnion;

    /** Method used to zero the remaining bytes of the address array when creating IPv4 addresses */
    void zeroUnusedBytes()
    {
        for (int i = 4; i < 16; ++i)
            address[i] = 0;
    }
};

} // namespace juce


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

class WebInputStream;

//==============================================================================
/**
    Represents a URL and has a bunch of useful functions to manipulate it.

    This class can be used to launch URLs in browsers, and also to create
    InputStreams that can read from remote http or ftp sources.
*/
class JUCE_API  URL
{
public:
    //==============================================================================
    /** Creates an empty URL. */
    URL() noexcept;

    /** Creates a URL from a string.
        This will parse any embedded parameters after a '?' character and store them
        in the list (see getParameterNames etc). If you don't want this to happen, you
        can use createWithoutParsing().
    */
    URL (const String& url);

    URL (const URL&) = default;
    URL& operator= (const URL&) = default;

    // VS2013 can't default move constructors and assignments
    URL (URL&&);
    URL& operator= (URL&&);

    /** Destructor. */
    ~URL();

    /** Compares two URLs.
        All aspects of the URLs must be identical for them to match, including any parameters,
        upload files, etc.
    */
    bool operator== (const URL&) const;
    bool operator!= (const URL&) const;

    //==============================================================================
    /** Returns a string version of the URL.

        If includeGetParameters is true and any parameters have been set with the
        withParameter() method, then the string will have these appended on the
        end and url-encoded.
    */
    String toString (bool includeGetParameters) const;

    /** Returns true if the URL is an empty string. */
    bool isEmpty() const noexcept;

    /** True if it seems to be valid. */
    bool isWellFormed() const;

    /** Returns just the domain part of the URL.
        E.g. for "http://www.xyz.com/foobar", this will return "www.xyz.com".
    */
    String getDomain() const;

    /** Returns the path part of the URL.
        E.g. for "http://www.xyz.com/foo/bar?x=1", this will return "foo/bar".
    */
    String getSubPath() const;

    /** Returns the scheme of the URL.
        E.g. for "http://www.xyz.com/foobar", this will return "http". (It won't
        include the colon).
    */
    String getScheme() const;

    /** Attempts to read a port number from the URL.
        @returns the port number, or 0 if none is explicitly specified.
    */
    int getPort() const;

    /** Returns a new version of this URL with a different domain and path.
        E.g. if the URL is "http://www.xyz.com/foo?x=1" and you call this with
        "abc.com/zzz", it'll return "http://abc.com/zzz?x=1".
        @see withNewSubPath
    */
    URL withNewDomainAndPath (const String& newFullPath) const;

    /** Returns a new version of this URL with a different sub-path.
        E.g. if the URL is "http://www.xyz.com/foo?x=1" and you call this with
        "bar", it'll return "http://www.xyz.com/bar?x=1".
        @see withNewDomainAndPath
    */
    URL withNewSubPath (const String& newPath) const;

    /** Returns a new URL that refers to a sub-path relative to this one.
        E.g. if the URL is "http://www.xyz.com/foo" and you call this with
        "bar", it'll return "http://www.xyz.com/foo/bar". Note that there's no way for
        this method to know whether the original URL is a file or directory, so it's
        up to you to make sure it's a directory. It also won't attempt to be smart about
        the content of the childPath string, so if this string is an absolute URL, it'll
        still just get bolted onto the end of the path.

        @see File::getChildFile
    */
    URL getChildURL (const String& subPath) const;

    //==============================================================================
    /** Returns a copy of this URL, with a GET or POST parameter added to the end.

        Any control characters in the value will be encoded.
        e.g. calling "withParameter ("amount", "some fish") for the url "www.fish.com"
        would produce a new url whose toString(true) method would return
        "www.fish.com?amount=some+fish".

        @see getParameterNames, getParameterValues
    */
    URL withParameter (const String& parameterName,
                       const String& parameterValue) const;

    /** Returns a copy of this URL, with a set of GET or POST parameters added.
        This is a convenience method, equivalent to calling withParameter for each value.
        @see withParameter
    */
    URL withParameters (const StringPairArray& parametersToAdd) const;

    /** Returns a copy of this URL, with a file-upload type parameter added to it.

        When performing a POST where one of your parameters is a binary file, this
        lets you specify the file.

        Note that the filename is stored, but the file itself won't actually be read
        until this URL is later used to create a network input stream. If you want to
        upload data from memory, use withDataToUpload().

        @see withDataToUpload
    */
    URL withFileToUpload (const String& parameterName,
                          const File& fileToUpload,
                          const String& mimeType) const;

    /** Returns a copy of this URL, with a file-upload type parameter added to it.

        When performing a POST where one of your parameters is a binary file, this
        lets you specify the file content.
        Note that the filename parameter should not be a full path, it's just the
        last part of the filename.

        @see withFileToUpload
    */
    URL withDataToUpload (const String& parameterName,
                          const String& filename,
                          const MemoryBlock& fileContentToUpload,
                          const String& mimeType) const;

    /** Returns an array of the names of all the URL's parameters.

        E.g. for the url "www.fish.com?type=haddock&amount=some+fish", this array would
        contain two items: "type" and "amount".

        You can call getParameterValues() to get the corresponding value of each
        parameter. Note that the list can contain multiple parameters with the same name.

        @see getParameterValues, withParameter
    */
    const StringArray& getParameterNames() const noexcept       { return parameterNames; }

    /** Returns an array of the values of all the URL's parameters.

        E.g. for the url "www.fish.com?type=haddock&amount=some+fish", this array would
        contain two items: "haddock" and "some fish".

        The values returned will have been cleaned up to remove any escape characters.

        You can call getParameterNames() to get the corresponding name of each
        parameter. Note that the list can contain multiple parameters with the same name.

        @see getParameterNames, withParameter
    */
    const StringArray& getParameterValues() const noexcept      { return parameterValues; }

    /** Returns a copy of this URL, with a block of data to send as the POST data.

        If you're setting the POST data, be careful not to have any parameters set
        as well, otherwise it'll all get thrown in together, and might not have the
        desired effect.

        If the URL already contains some POST data, this will replace it, rather
        than being appended to it.

        This data will only be used if you specify a post operation when you call
        createInputStream().
    */
    URL withPOSTData (const String& postData) const;

    /** Returns a copy of this URL, with a block of data to send as the POST data.

        If you're setting the POST data, be careful not to have any parameters set
        as well, otherwise it'll all get thrown in together, and might not have the
        desired effect.

        If the URL already contains some POST data, this will replace it, rather
        than being appended to it.

        This data will only be used if you specify a post operation when you call
        createInputStream().
    */
    URL withPOSTData (const MemoryBlock& postData) const;

    /** Returns the data that was set using withPOSTData(). */
    String getPostData() const noexcept                             { return postData.toString(); }

    /** Returns the data that was set using withPOSTData() as MemoryBlock. */
    const MemoryBlock& getPostDataAsMemoryBlock() const noexcept    { return postData; }

    //==============================================================================
    /** Tries to launch the system's default browser to open the URL.
        Returns true if this seems to have worked.
    */
    bool launchInDefaultBrowser() const;

    //==============================================================================
    /** Takes a guess as to whether a string might be a valid website address.
        This isn't foolproof!
    */
    static bool isProbablyAWebsiteURL (const String& possibleURL);

    /** Takes a guess as to whether a string might be a valid email address.
        This isn't foolproof!
    */
    static bool isProbablyAnEmailAddress (const String& possibleEmailAddress);

    //==============================================================================
    /** This callback function can be used by the createInputStream() method.

        It allows your app to receive progress updates during a lengthy POST operation. If you
        want to continue the operation, this should return true, or false to abort.
    */
    typedef bool (OpenStreamProgressCallback) (void* context, int bytesSent, int totalBytes);

    /** Attempts to open a stream that can read from this URL.

        This method is a convenience wrapper for creating a new WebInputStream and setting some
        commonly used options. The returned WebInputStream will have already been connected and
        reading can start instantly.

        Note that this method will block until the first byte of data has been received or an
        error has occurred.

        Note that on some platforms (Android, for example) it's not permitted to do any network
        action from the message thread, so you must only call it from a background thread.

        @param doPostLikeRequest if true, the parameters added to this class will be transferred
                                 via the HTTP headers which is typical for POST requests. Otherwise
                                 the parameters will be added to the URL address. Additionally,
                                 if the parameter httpRequestCmd is not specified (or empty) then this
                                 parameter will determine which HTTP request command will be used
                                 (POST or GET).
        @param progressCallback  if this is not a nullptr, it lets you supply a callback function
                                 to keep track of the operation's progress. This can be useful
                                 for lengthy POST operations, so that you can provide user feedback.
        @param progressCallbackContext  if a callback is specified, this value will be passed to
                                 the function
        @param extraHeaders      if not empty, this string is appended onto the headers that
                                 are used for the request. It must therefore be a valid set of HTML
                                 header directives, separated by newlines.
        @param connectionTimeOutMs  if 0, this will use whatever default setting the OS chooses. If
                                 a negative number, it will be infinite. Otherwise it specifies a
                                 time in milliseconds.
        @param responseHeaders   if this is non-null, all the (key, value) pairs received as headers
                                 in the response will be stored in this array
        @param statusCode        if this is non-null, it will get set to the http status code, if one
                                 is known, or 0 if a code isn't available
        @param numRedirectsToFollow specifies the number of redirects that will be followed before
                                 returning a response (ignored for Android which follows up to 5 redirects)
        @param httpRequestCmd    Specify which HTTP Request to use. If this is empty, then doPostRequest
                                 will determine the HTTP request.
        @returns    an input stream that the caller must delete, or a null pointer if there was an
                    error trying to open it.
     */
    WebInputStream* createInputStream (bool doPostLikeRequest,
                                       OpenStreamProgressCallback* progressCallback = nullptr,
                                       void* progressCallbackContext = nullptr,
                                       String extraHeaders = String(),
                                       int connectionTimeOutMs = 0,
                                       StringPairArray* responseHeaders = nullptr,
                                       int* statusCode = nullptr,
                                       int numRedirectsToFollow = 5,
                                       String httpRequestCmd = String()) const;

    //==============================================================================
    /** Represents a download task.
        Returned by downloadToFile to allow querying and controling the download task.
    */
    class DownloadTask
    {
    public:
        struct Listener
        {
            virtual ~Listener();

            /** Called when the download has finished. Be aware that this callback may
                come on an arbitrary thread. */
            virtual void finished (DownloadTask* task, bool success) = 0;

            /** Called periodically by the OS to indicate download progress.
                Beware that this callback may come on an arbitrary thread.
            */
            virtual void progress (DownloadTask* task, int64 bytesDownloaded, int64 totalLength);
        };

        /** Releases the resources of the download task, unregisters the listener
            and cancels the download if necessary. */
        virtual ~DownloadTask();

        /** Returns the total length of the download task. This may return -1 if the length
            was not returned by the server. */
        int64 getTotalLength() const                      { return contentLength; }

        /** Returns the number of bytes that have been downloaded so far. */
        int64 getLengthDownloaded() const                 { return downloaded; }

        /** Returns true if the download finished or there was an error. */
        bool isFinished() const                           { return finished; }

        /** Returns the status code of the server's response.
            This will only be valid after the download has finished.
            @see isFinished
        */
        int statusCode() const                            { return httpCode; }

        /** Returns true if there was an error. */
        inline bool hadError() const                      { return error; }

    protected:
        int64 contentLength = -1, downloaded = 0;
        bool finished = false, error = false;
        int httpCode = -1;

        DownloadTask();

    private:
        friend class URL;
        static DownloadTask* createFallbackDownloader (const URL&, const File&, const String&, Listener*, bool);

    public:
       #if JUCE_IOS
        /** internal **/
        static void juce_iosURLSessionNotify (const String&);
       #endif

    private:
        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DownloadTask)
    };

    /** Download the URL to a file.

        This method attempts to download the URL to a given file location.

        Using this method to download files on mobile is less flexible but more reliable
        than using createInputStream or WebInputStreams as it will attempt to download the file
        using a native OS background network task. Such tasks automatically deal with
        network re-connections and continuing your download while your app is suspended.
    */
    DownloadTask* downloadToFile (const File& targetLocation,
                                  String extraHeaders = String(),
                                  DownloadTask::Listener* listener = nullptr,
                                  bool usePostCommand = false);

    //==============================================================================
    /** Tries to download the entire contents of this URL into a binary data block.

        If it succeeds, this will return true and append the data it read onto the end
        of the memory block.

        Note that on some platforms (Android, for example) it's not permitted to do any network
        action from the message thread, so you must only call it from a background thread.

        @param destData         the memory block to append the new data to
        @param usePostCommand   whether to use a POST command to get the data (uses
                                a GET command if this is false)
        @see readEntireTextStream, readEntireXmlStream
    */
    bool readEntireBinaryStream (MemoryBlock& destData,
                                 bool usePostCommand = false) const;

    /** Tries to download the entire contents of this URL as a string.

        If it fails, this will return an empty string, otherwise it will return the
        contents of the downloaded file. If you need to distinguish between a read
        operation that fails and one that returns an empty string, you'll need to use
        a different method, such as readEntireBinaryStream().

        Note that on some platforms (Android, for example) it's not permitted to do any network
        action from the message thread, so you must only call it from a background thread.

        @param usePostCommand   whether to use a POST command to get the data (uses
                                a GET command if this is false)
        @see readEntireBinaryStream, readEntireXmlStream
    */
    String readEntireTextStream (bool usePostCommand = false) const;

    /** Tries to download the entire contents of this URL and parse it as XML.

        If it fails, or if the text that it reads can't be parsed as XML, this will
        return nullptr.

        When it returns a valid XmlElement object, the caller is responsibile for deleting
        this object when no longer needed.

        Note that on some platforms (Android, for example) it's not permitted to do any network
        action from the message thread, so you must only call it from a background thread.

        @param usePostCommand   whether to use a POST command to get the data (uses
                                a GET command if this is false)

        @see readEntireBinaryStream, readEntireTextStream
    */
    XmlElement* readEntireXmlStream (bool usePostCommand = false) const;

    //==============================================================================
    /** Adds escape sequences to a string to encode any characters that aren't
        legal in a URL.

        E.g. any spaces will be replaced with "%20".

        This is the opposite of removeEscapeChars().

        @param stringToAddEscapeCharsTo The string to escape.
        @param isParameter              If true then the string is going to be
                                        used as a parameter, so it also encodes
                                        '$' and ',' (which would otherwise be
                                        legal in a URL.
        @param roundBracketsAreLegal    Technically round brackets are ok in URLs,
                                        however, some servers (like AWS) also want
                                        round brackets to be escaped.

        @see removeEscapeChars
    */
    static String addEscapeChars (const String& stringToAddEscapeCharsTo,
                                  bool isParameter,
                                  bool roundBracketsAreLegal = true);

    /** Replaces any escape character sequences in a string with their original
        character codes.

        E.g. any instances of "%20" will be replaced by a space.

        This is the opposite of addEscapeChars().

        @see addEscapeChars
    */
    static String removeEscapeChars (const String& stringToRemoveEscapeCharsFrom);

    /** Returns a URL without attempting to remove any embedded parameters from the string.
        This may be necessary if you need to create a request that involves both POST
        parameters and parameters which are embedded in the URL address itself.
    */
    static URL createWithoutParsing (const String& url);

private:
    //==============================================================================
    friend class WebInputStream;

    String url;
    MemoryBlock postData;
    StringArray parameterNames, parameterValues;

    struct Upload  : public ReferenceCountedObject
    {
        Upload (const String&, const String&, const String&, const File&, MemoryBlock*);
        String parameterName, filename, mimeType;
        File file;
        ScopedPointer<MemoryBlock> data;

        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Upload)
    };

    friend struct ContainerDeletePolicy<Upload>;
    ReferenceCountedArray<Upload> filesToUpload;

    URL (const String&, int);
    void addParameter (const String&, const String&);
    void createHeadersAndPostData (String&, MemoryBlock&) const;
    URL withUpload (Upload*) const;

    JUCE_LEAK_DETECTOR (URL)
};

} // namespace juce


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

NamedPipe::NamedPipe() {}

NamedPipe::~NamedPipe()
{
    close();
}

bool NamedPipe::openExisting (const String& pipeName)
{
    close();

    ScopedWriteLock sl (lock);
    currentPipeName = pipeName;
    return openInternal (pipeName, false, false);
}

bool NamedPipe::isOpen() const
{
    return pimpl != nullptr;
}

bool NamedPipe::createNewPipe (const String& pipeName, bool mustNotExist)
{
    close();

    ScopedWriteLock sl (lock);
    currentPipeName = pipeName;
    return openInternal (pipeName, true, mustNotExist);
}

String NamedPipe::getName() const
{
    return currentPipeName;
}

// other methods for this class are implemented in the platform-specific files

} // namespace juce


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

//==============================================================================
/**
    An InputStream which can be used to read from a given url.
*/
class JUCE_API WebInputStream : public InputStream
{
 public:
    class JUCE_API Listener
    {
    public:
        virtual ~Listener() {}

        virtual bool postDataSendProgress (WebInputStream& /*request*/, int /*bytesSent*/, int /*totalBytes*/)    { return true; }
    };

    /** Creates a new WebInputstream which can be used to read from a url.

        @param url      The url that should be retrieved. This parameter may also contain
                        post data and/or parameters.
        @param usePost  Specifies wheather a GET or a POST command should be used. This
                        parameter will also influence the way parameters are encoded.
    */
    WebInputStream (const URL& url, const bool usePost);

    ~WebInputStream();

    /** Add extra headers to http request

        Returns a reference to itself so that several methods can be chained.

        @param extraHeaders   this string is appended onto the headers that are used for
                              the request. It must therefore be a valid set of HTML
                              header directives, separated by newlines.
    */
    WebInputStream& withExtraHeaders (const String& extraHeaders);

    /** Override the http command that is sent

        Returns a reference to itself so that several methods can be chained.

        Note that this command will not change the way parameters are sent. This
        must be specified in the constructor.

        @param customRequestCommand this string is the custom http request command such
                                    as POST or GET.
    */
    WebInputStream& withCustomRequestCommand (const String& customRequestCommand);

    /** Specify the connection time-out

        Returns a reference to itself so that several methods can be chained.

        @param timeoutInMs    the number of milliseconds to wait until the connection
                              request is aborted.
    */
    WebInputStream& withConnectionTimeout (int timeoutInMs);

    /** Specify the number of redirects to be followed

        Returns a reference to itself so that several methods can be chained.

        @param numRedirects specifies the number of redirects that will be followed
                            before returning a response (ignored for Android which
                            follows up to 5 redirects)
    */
    WebInputStream& withNumRedirectsToFollow (int numRedirects);

    /** Returns a string array pair of the request headers */
    StringPairArray getRequestHeaders() const;

    /** Returns a string array pair of response headers

        If getResponseHeaders is called without an established connection, then
        getResponseHeaders will call connect internally and block until connect
        returns - either due to a succesful connection or a connection
        error.

        @see connect
    */
    StringPairArray getResponseHeaders();

    /** Returns the status code returned by the http server

        If getStatusCode is called without an established connection, then
        getStatusCode will call connect internally and block until connect
        returns - either due to a succesful connection or a connection
        error.

        @see connect
    */
    int getStatusCode();

    /** Wait until the first byte is ready for reading

        This method will attempt to connect to the url given in the constructor
        and block until the status code and all response headers have been received or
        an error has occurred.

        Note that most methods will call connect internally if they are called without
        an established connection. Therefore, it is not necessary to explicitly
        call connect unless you would like to use a custom listener.

        After a successful call to connect, getResponseHeaders, getTotalLength and
        getStatusCode will all be non-blocking.

        @param listener    A listener to receive progress callbacks on the status
                           of a POST data upload.

        @see getResponseHeaders, getTotalLength, getStatusCode
    */
    bool connect (Listener* listener);

    /** Returns true if there was an error during the connection attempt. */
    bool isError() const;

    /** Will cancel a blocking read and prevent any subsequent connection attempts. */
    void cancel();

    //==============================================================================
    /** Returns the total number of bytes available for reading in this stream.

        Note that this is the number of bytes available from the start of the
        stream, not from the current position.

        If getTotalLength is called without an established connection, then
        getTotalLength will call connect internally and block until connect
        returns - either due to a succesful connection or a connection
        error.

        If the size of the stream isn't actually known, this will return -1.
    */
    int64 getTotalLength() override;

    /** Reads some data from the stream into a memory buffer.

        This method will block until the bytesToRead bytes are available.

        This method calls connect internally if the connection hasn't already
        been established.

        @param destBuffer       the destination buffer for the data. This must not be null.
        @param maxBytesToRead   the maximum number of bytes to read - make sure the
                                memory block passed in is big enough to contain this
                                many bytes. This value must not be negative.

        @returns    the actual number of bytes that were read, which may be less than
                    maxBytesToRead if the stream is exhausted before it gets that far
    */
    int read (void* destBuffer, int maxBytesToRead) override;

    /** Returns true if the stream has no more data to read. */
    bool isExhausted() override;

    /** Returns the offset of the next byte that will be read from the stream.
        @see setPosition
    */
    int64 getPosition() override;

    /** Tries to move the current read position of the stream.

        The position is an absolute number of bytes from the stream's start.

        For a WebInputStream, this method will fail if wantedPos is smaller
        than the curent position. If wantedPos is greater than the current
        position, then calling setPosition is the same as calling read, i.e.
        the skipped data will still be downloaded, although skipped bytes will
        be discarded immedietely.

        @returns  true if the stream manages to reposition itself correctly
        @see getPosition
    */
    bool setPosition (int64 wantedPos) override;

 private:
    static void createHeadersAndPostData (const URL&, String&, MemoryBlock&);
    static StringPairArray parseHttpHeaders (const String& headerData);

    class Pimpl;
    friend class Pimpl;

    Pimpl* const pimpl;
    bool hasCalledConnect;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebInputStream)
};

} // namespace juce


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

//==============================================================================
/**
    This class acts as a pointer which will automatically become null if the object
    to which it points is deleted.

    To accomplish this, the source object needs to cooperate by performing a couple of simple tasks.
    It must embed a WeakReference::Master object, which stores a shared pointer object, and must clear
    this master pointer in its destructor.

    E.g.
    @code
    class MyObject
    {
    public:
        MyObject()
        {
            // If you're planning on using your WeakReferences in a multi-threaded situation, you may choose
            // to create a WeakReference to the object here in the constructor, which will pre-initialise the
            // embedded object, avoiding an (extremely unlikely) race condition that could occur if multiple
            // threads overlap while creating the first WeakReference to it.
        }

        ~MyObject()
        {
            // This will zero all the references - you need to call this in your destructor.
            masterReference.clear();
        }

    private:
        // You need to embed a variable of this type, with the name "masterReference" inside your object. If the
        // variable is not public, you should make your class a friend of WeakReference<MyObject> so that the
        // WeakReference class can access it.
        WeakReference<MyObject>::Master masterReference;
        friend class WeakReference<MyObject>;
    };

    OR: just use the handy JUCE_DECLARE_WEAK_REFERENCEABLE macro to do all this for you.

    // Here's an example of using a pointer..

    MyObject* n = new MyObject();
    WeakReference<MyObject> myObjectRef = n;

    MyObject* pointer1 = myObjectRef;  // returns a valid pointer to 'n'
    delete n;
    MyObject* pointer2 = myObjectRef;  // returns a null pointer
    @endcode

    @see WeakReference::Master
*/
template <class ObjectType, class ReferenceCountingType = ReferenceCountedObject>
class WeakReference
{
public:
    /** Creates a null SafePointer. */
    inline WeakReference() noexcept {}

    /** Creates a WeakReference that points at the given object. */
    WeakReference (ObjectType* const object)  : holder (getRef (object)) {}

    /** Creates a copy of another WeakReference. */
    WeakReference (const WeakReference& other) noexcept         : holder (other.holder) {}

    /** Move constructor */
    WeakReference (WeakReference&& other) noexcept              : holder (static_cast<SharedRef&&> (other.holder)) {}

    /** Copies another pointer to this one. */
    WeakReference& operator= (const WeakReference& other)       { holder = other.holder; return *this; }

    /** Copies another pointer to this one. */
    WeakReference& operator= (ObjectType* const newObject)      { holder = getRef (newObject); return *this; }

    /** Move assignment operator */
    WeakReference& operator= (WeakReference&& other) noexcept   { holder = static_cast<SharedRef&&> (other.holder); return *this; }

    /** Returns the object that this pointer refers to, or null if the object no longer exists. */
    ObjectType* get() const noexcept                            { return holder != nullptr ? holder->get() : nullptr; }

    /** Returns the object that this pointer refers to, or null if the object no longer exists. */
    operator ObjectType*() const noexcept                       { return get(); }

    /** Returns the object that this pointer refers to, or null if the object no longer exists. */
    ObjectType* operator->() noexcept                           { return get(); }

    /** Returns the object that this pointer refers to, or null if the object no longer exists. */
    const ObjectType* operator->() const noexcept               { return get(); }

    /** This returns true if this reference has been pointing at an object, but that object has
        since been deleted.

        If this reference was only ever pointing at a null pointer, this will return false. Using
        operator=() to make this refer to a different object will reset this flag to match the status
        of the reference from which you're copying.
    */
    bool wasObjectDeleted() const noexcept                      { return holder != nullptr && holder->get() == nullptr; }

    bool operator== (ObjectType* const object) const noexcept   { return get() == object; }
    bool operator!= (ObjectType* const object) const noexcept   { return get() != object; }

    //==============================================================================
    /** This class is used internally by the WeakReference class - don't use it directly
        in your code!
        @see WeakReference
    */
    class SharedPointer   : public ReferenceCountingType
    {
    public:
        explicit SharedPointer (ObjectType* const obj) noexcept : owner (obj) {}

        inline ObjectType* get() const noexcept     { return owner; }
        void clearPointer() noexcept                { owner = nullptr; }

    private:
        ObjectType* volatile owner;

        JUCE_DECLARE_NON_COPYABLE (SharedPointer)
    };

    typedef ReferenceCountedObjectPtr<SharedPointer> SharedRef;

    //==============================================================================
    /**
        This class is embedded inside an object to which you want to attach WeakReference pointers.
        See the WeakReference class notes for an example of how to use this class.
        @see WeakReference
    */
    class Master
    {
    public:
        Master() noexcept {}

        ~Master() noexcept
        {
            // You must remember to call clear() in your source object's destructor! See the notes
            // for the WeakReference class for an example of how to do this.
            jassert (sharedPointer == nullptr || sharedPointer->get() == nullptr);
        }

        /** The first call to this method will create an internal object that is shared by all weak
            references to the object.
        */
        SharedPointer* getSharedPointer (ObjectType* const object)
        {
            if (sharedPointer == nullptr)
            {
                sharedPointer = new SharedPointer (object);
            }
            else
            {
                // You're trying to create a weak reference to an object that has already been deleted!!
                jassert (sharedPointer->get() != nullptr);
            }

            return sharedPointer;
        }

        /** The object that owns this master pointer should call this before it gets destroyed,
            to zero all the references to this object that may be out there. See the WeakReference
            class notes for an example of how to do this.
        */
        void clear() noexcept
        {
            if (sharedPointer != nullptr)
                sharedPointer->clearPointer();
        }

        /** Returns the number of WeakReferences that are out there pointing to this object. */
        int getNumActiveWeakReferences() const noexcept
        {
            return sharedPointer == nullptr ? 0 : (sharedPointer->getReferenceCount() - 1);
        }

    private:
        SharedRef sharedPointer;

        JUCE_DECLARE_NON_COPYABLE (Master)
    };

private:
    SharedRef holder;

    static inline SharedPointer* getRef (ObjectType* const o)
    {
        return (o != nullptr) ? o->masterReference.getSharedPointer (o) : nullptr;
    }
};

//==============================================================================
/**
     Macro to easily allow a class to be made weak-referenceable.
     This can be inserted in a class definition to add the requisite weak-ref boilerplate to that class.
     e.g.

     @code
     class MyObject
     {
     public:
         MyObject();
         ~MyObject();

     private:
         JUCE_DECLARE_WEAK_REFERENCEABLE (MyObject)
     };
     @endcode

     @see WeakReference, WeakReference::Master
*/
#define JUCE_DECLARE_WEAK_REFERENCEABLE(Class) \
    struct WeakRefMaster  : public WeakReference<Class>::Master { ~WeakRefMaster() { this->clear(); } }; \
    WeakRefMaster masterReference; \
    friend class WeakReference<Class>; \

} // namespace juce


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

#if ! (defined (DOXYGEN) || JUCE_EXCEPTIONS_DISABLED)
namespace HeapBlockHelper
{
    template <bool shouldThrow>
    struct ThrowOnFail          { static void checkPointer (void*) {} };

    template<>
    struct ThrowOnFail<true>    { static void checkPointer (void* data) { if (data == nullptr) throw std::bad_alloc(); } };
}
#endif

//==============================================================================
/**
    Very simple container class to hold a pointer to some data on the heap.

    When you need to allocate some heap storage for something, always try to use
    this class instead of allocating the memory directly using malloc/free.

    A HeapBlock<char> object can be treated in pretty much exactly the same way
    as an char*, but as long as you allocate it on the stack or as a class member,
    it's almost impossible for it to leak memory.

    It also makes your code much more concise and readable than doing the same thing
    using direct allocations,

    E.g. instead of this:
    @code
        int* temp = (int*) malloc (1024 * sizeof (int));
        memcpy (temp, xyz, 1024 * sizeof (int));
        free (temp);
        temp = (int*) calloc (2048 * sizeof (int));
        temp[0] = 1234;
        memcpy (foobar, temp, 2048 * sizeof (int));
        free (temp);
    @endcode

    ..you could just write this:
    @code
        HeapBlock<int> temp (1024);
        memcpy (temp, xyz, 1024 * sizeof (int));
        temp.calloc (2048);
        temp[0] = 1234;
        memcpy (foobar, temp, 2048 * sizeof (int));
    @endcode

    The class is extremely lightweight, containing only a pointer to the
    data, and exposes malloc/realloc/calloc/free methods that do the same jobs
    as their less object-oriented counterparts. Despite adding safety, you probably
    won't sacrifice any performance by using this in place of normal pointers.

    The throwOnFailure template parameter can be set to true if you'd like the class
    to throw a std::bad_alloc exception when an allocation fails. If this is false,
    then a failed allocation will just leave the heapblock with a null pointer (assuming
    that the system's malloc() function doesn't throw).

    @see Array, OwnedArray, MemoryBlock
*/
template <class ElementType, bool throwOnFailure = false>
class HeapBlock
{
public:
    //==============================================================================
    /** Creates a HeapBlock which is initially just a null pointer.

        After creation, you can resize the array using the malloc(), calloc(),
        or realloc() methods.
    */
    HeapBlock() noexcept
    {
    }

    /** Creates a HeapBlock containing a number of elements.

        The contents of the block are undefined, as it will have been created by a
        malloc call.

        If you want an array of zero values, you can use the calloc() method or the
        other constructor that takes an InitialisationState parameter.
    */
    template <typename SizeType>
    explicit HeapBlock (SizeType numElements)
        : data (static_cast<ElementType*> (std::malloc (static_cast<size_t> (numElements) * sizeof (ElementType))))
    {
        throwOnAllocationFailure();
    }

    /** Creates a HeapBlock containing a number of elements.

        The initialiseToZero parameter determines whether the new memory should be cleared,
        or left uninitialised.
    */
    template <typename SizeType>
    HeapBlock (SizeType numElements, bool initialiseToZero)
        : data (static_cast<ElementType*> (initialiseToZero
                                               ? std::calloc (static_cast<size_t> (numElements), sizeof (ElementType))
                                               : std::malloc (static_cast<size_t> (numElements) * sizeof (ElementType))))
    {
        throwOnAllocationFailure();
    }

    /** Destructor.
        This will free the data, if any has been allocated.
    */
    ~HeapBlock()
    {
        std::free (data);
    }

    /** Move constructor */
    HeapBlock (HeapBlock&& other) noexcept
        : data (other.data)
    {
        other.data = nullptr;
    }

    /** Move assignment operator */
    HeapBlock& operator= (HeapBlock&& other) noexcept
    {
        std::swap (data, other.data);
        return *this;
    }

    //==============================================================================
    /** Returns a raw pointer to the allocated data.
        This may be a null pointer if the data hasn't yet been allocated, or if it has been
        freed by calling the free() method.
    */
    inline operator ElementType*() const noexcept                            { return data; }

    /** Returns a raw pointer to the allocated data.
        This may be a null pointer if the data hasn't yet been allocated, or if it has been
        freed by calling the free() method.
    */
    inline ElementType* get() const noexcept                                 { return data; }

    /** Returns a raw pointer to the allocated data.
        This may be a null pointer if the data hasn't yet been allocated, or if it has been
        freed by calling the free() method.
    */
    inline ElementType* getData() const noexcept                             { return data; }

    /** Returns a void pointer to the allocated data.
        This may be a null pointer if the data hasn't yet been allocated, or if it has been
        freed by calling the free() method.
    */
    inline operator void*() const noexcept                                   { return static_cast<void*> (data); }

    /** Returns a void pointer to the allocated data.
        This may be a null pointer if the data hasn't yet been allocated, or if it has been
        freed by calling the free() method.
    */
    inline operator const void*() const noexcept                             { return static_cast<const void*> (data); }

    /** Lets you use indirect calls to the first element in the array.
        Obviously this will cause problems if the array hasn't been initialised, because it'll
        be referencing a null pointer.
    */
    inline ElementType* operator->() const  noexcept                         { return data; }

    /** Returns a reference to one of the data elements.
        Obviously there's no bounds-checking here, as this object is just a dumb pointer and
        has no idea of the size it currently has allocated.
    */
    template <typename IndexType>
    ElementType& operator[] (IndexType index) const noexcept                 { return data [index]; }

    /** Returns a pointer to a data element at an offset from the start of the array.
        This is the same as doing pointer arithmetic on the raw pointer itself.
    */
    template <typename IndexType>
    ElementType* operator+ (IndexType index) const noexcept                  { return data + index; }

    //==============================================================================
    /** Compares the pointer with another pointer.
        This can be handy for checking whether this is a null pointer.
    */
    inline bool operator== (const ElementType* otherPointer) const noexcept  { return otherPointer == data; }

    /** Compares the pointer with another pointer.
        This can be handy for checking whether this is a null pointer.
    */
    inline bool operator!= (const ElementType* otherPointer) const noexcept  { return otherPointer != data; }

    //==============================================================================
    /** Allocates a specified amount of memory.

        This uses the normal malloc to allocate an amount of memory for this object.
        Any previously allocated memory will be freed by this method.

        The number of bytes allocated will be (newNumElements * elementSize). Normally
        you wouldn't need to specify the second parameter, but it can be handy if you need
        to allocate a size in bytes rather than in terms of the number of elements.

        The data that is allocated will be freed when this object is deleted, or when you
        call free() or any of the allocation methods.
    */
    template <typename SizeType>
    void malloc (SizeType newNumElements, size_t elementSize = sizeof (ElementType))
    {
        std::free (data);
        data = static_cast<ElementType*> (std::malloc (static_cast<size_t> (newNumElements) * elementSize));
        throwOnAllocationFailure();
    }

    /** Allocates a specified amount of memory and clears it.
        This does the same job as the malloc() method, but clears the memory that it allocates.
    */
    template <typename SizeType>
    void calloc (SizeType newNumElements, const size_t elementSize = sizeof (ElementType))
    {
        std::free (data);
        data = static_cast<ElementType*> (std::calloc (static_cast<size_t> (newNumElements), elementSize));
        throwOnAllocationFailure();
    }

    /** Allocates a specified amount of memory and optionally clears it.
        This does the same job as either malloc() or calloc(), depending on the
        initialiseToZero parameter.
    */
    template <typename SizeType>
    void allocate (SizeType newNumElements, bool initialiseToZero)
    {
        std::free (data);
        data = static_cast<ElementType*> (initialiseToZero
                                             ? std::calloc (static_cast<size_t> (newNumElements), sizeof (ElementType))
                                             : std::malloc (static_cast<size_t> (newNumElements) * sizeof (ElementType)));
        throwOnAllocationFailure();
    }

    /** Re-allocates a specified amount of memory.

        The semantics of this method are the same as malloc() and calloc(), but it
        uses realloc() to keep as much of the existing data as possible.
    */
    template <typename SizeType>
    void realloc (SizeType newNumElements, size_t elementSize = sizeof (ElementType))
    {
        data = static_cast<ElementType*> (data == nullptr ? std::malloc (static_cast<size_t> (newNumElements) * elementSize)
                                                          : std::realloc (data, static_cast<size_t> (newNumElements) * elementSize));
        throwOnAllocationFailure();
    }

    /** Frees any currently-allocated data.
        This will free the data and reset this object to be a null pointer.
    */
    void free() noexcept
    {
        std::free (data);
        data = nullptr;
    }

    /** Swaps this object's data with the data of another HeapBlock.
        The two objects simply exchange their data pointers.
    */
    template <bool otherBlockThrows>
    void swapWith (HeapBlock<ElementType, otherBlockThrows>& other) noexcept
    {
        std::swap (data, other.data);
    }

    /** This fills the block with zeros, up to the number of elements specified.
        Since the block has no way of knowing its own size, you must make sure that the number of
        elements you specify doesn't exceed the allocated size.
    */
    template <typename SizeType>
    void clear (SizeType numElements) noexcept
    {
        zeromem (data, sizeof (ElementType) * static_cast<size_t> (numElements));
    }

    /** This typedef can be used to get the type of the heapblock's elements. */
    typedef ElementType Type;

private:
    //==============================================================================
    ElementType* data = nullptr;

    void throwOnAllocationFailure() const
    {
       #if JUCE_EXCEPTIONS_DISABLED
        jassert (data != nullptr); // without exceptions, you'll need to find a better way to handle this failure case.
       #else
        HeapBlockHelper::ThrowOnFail<throwOnFailure>::checkPointer (data);
       #endif
    }

   #if ! (defined (JUCE_DLL) || defined (JUCE_DLL_BUILD))
    JUCE_DECLARE_NON_COPYABLE (HeapBlock)
    JUCE_PREVENT_HEAP_ALLOCATION // Creating a 'new HeapBlock' would be missing the point!
   #endif
};

} // namespace juce


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

//==============================================================================
/**
    Used by container classes as an indirect way to delete an object of a
    particular type.

    The generic implementation of this class simply calls 'delete', but you can
    create a specialised version of it for a particular class if you need to
    delete that type of object in a more appropriate way.

    @see ScopedPointer, OwnedArray
*/
template <typename ObjectType>
struct ContainerDeletePolicy
{
    static void destroy (ObjectType* object)
    {
        // If the line below triggers a compiler error, it means that you are using
        // an incomplete type for ObjectType (for example, a type that is declared
        // but not defined). This is a problem because then the following delete is
        // undefined behaviour. The purpose of the sizeof is to capture this situation.
        // If this was caused by a ScopedPointer to a forward-declared type, move the
        // implementation of all methods trying to use the ScopedPointer (e.g. the destructor
        // of the class owning it) into cpp files where they can see to the definition
        // of ObjectType. This should fix the error.
        ignoreUnused (sizeof (ObjectType));

        delete object;
    }
};

} // namespace juce


text:
/*
  ==============================================================================

   This file is part of the JUCE library.
   Copyright (c) 2017 - ROLI Ltd.

   JUCE is an open source library subject to commercial or open-source
   licensing.

   The code included in this file is provided under the terms of the ISC license
   http://www.isc.org/downloads/software-support-policy/isc-license. Permission
   To use, copy, modify, and/or distribute this software for any purpose with or
   without fee is hereby granted provided that the above copyright notice and
   this permission notice appear in all copies.

   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
   DISCLAIMED.

  ==============================================================================
*/

namespace juce
{

//==============================================================================
/**
    Holds a pointer to an object which can optionally be deleted when this pointer
    goes out of scope.

    This acts in many ways like a ScopedPointer, but allows you to specify whether or
    not the object is deleted.

    @see ScopedPointer
*/
template <class ObjectType>
class OptionalScopedPointer
{
public:
    //==============================================================================
    /** Creates an empty OptionalScopedPointer. */
    OptionalScopedPointer() : shouldDelete (false) {}

    /** Creates an OptionalScopedPointer to point to a given object, and specifying whether
        the OptionalScopedPointer will delete it.

        If takeOwnership is true, then the OptionalScopedPointer will act like a ScopedPointer,
        deleting the object when it is itself deleted. If this parameter is false, then the
        OptionalScopedPointer just holds a normal pointer to the object, and won't delete it.
    */
    OptionalScopedPointer (ObjectType* objectToHold, bool takeOwnership)
        : object (objectToHold), shouldDelete (takeOwnership)
    {
    }

    /** Takes ownership of the object that another OptionalScopedPointer holds.

        Like a normal ScopedPointer, the objectToTransferFrom object will become null,
        as ownership of the managed object is transferred to this object.

        The flag to indicate whether or not to delete the managed object is also
        copied from the source object.
    */
    OptionalScopedPointer (OptionalScopedPointer& objectToTransferFrom)
        : object (objectToTransferFrom.release()),
          shouldDelete (objectToTransferFrom.shouldDelete)
    {
    }

    /** Takes ownership of the object that another OptionalScopedPointer holds.

        Like a normal ScopedPointer, the objectToTransferFrom object will become null,
        as ownership of the managed object is transferred to this object.

        The ownership flag that says whether or not to delete the managed object is also
        copied from the source object.
    */
    OptionalScopedPointer& operator= (OptionalScopedPointer& objectToTransferFrom)
    {
        if (object != objectToTransferFrom.object)
        {
            clear();
            object = objectToTransferFrom.object;
        }

        shouldDelete = objectToTransferFrom.shouldDelete;
        return *this;
    }

    /** The destructor may or may not delete the object that is being held, depending on the
        takeOwnership flag that was specified when the object was first passed into an
        OptionalScopedPointer constructor.
    */
    ~OptionalScopedPointer()
    {
        clear();
    }

    //==============================================================================
    /** Returns the object that this pointer is managing. */
    inline operator ObjectType*() const noexcept                    { return object; }

    /** Returns the object that this pointer is managing. */
    inline ObjectType* get() const noexcept                         { return object; }

    /** Returns the object that this pointer is managing. */
    inline ObjectType& operator*() const noexcept                   { return *object; }

    /** Lets you access methods and properties of the object that this pointer is holding. */
    inline ObjectType* operator->() const noexcept                  { return object; }

    //==============================================================================
    /** Removes the current object from this OptionalScopedPointer without deleting it.
        This will return the current object, and set this OptionalScopedPointer to a null pointer.
    */
    ObjectType* release() noexcept                                  { return object.release(); }

    /** Resets this pointer to null, possibly deleting the object that it holds, if it has
        ownership of it.
    */
    void clear()
    {
        if (! shouldDelete)
            object.release();
    }

    /** Makes this OptionalScopedPointer point at a new object, specifying whether the
        OptionalScopedPointer will take ownership of the object.

        If takeOwnership is true, then the OptionalScopedPointer will act like a ScopedPointer,
        deleting the object when it is itself deleted. If this parameter is false, then the
        OptionalScopedPointer just holds a normal pointer to the object, and won't delete it.
    */
    void set (ObjectType* newObject, bool takeOwnership)
    {
        if (object != newObject)
        {
            clear();
            object = newObject;
        }

        shouldDelete = takeOwnership;
    }

    /** Makes this OptionalScopedPointer point at a new object, and take ownership of that object. */
    void setOwned (ObjectType* newObject)
    {
        set (newObject, true);
    }

    /** Makes this OptionalScopedPointer point at a new object, but will not take ownership of that object. */
    void setNonOwned (ObjectType* newObject)
    {
        set (newObject, false);
    }

    /** Returns true if the target object will be deleted when this pointer
        object is deleted.
    */
    bool willDeleteObject() const noexcept                          { return shouldDelete; }

    //==============================================================================
    /** Swaps this object with another OptionalScopedPointer.
        The two objects simply exchange their states.
    */
    void swapWith (OptionalScopedPointer<ObjectType>& other) noexcept
    {
        object.swapWith (other.object);
        std::swap (shouldDelete, other.shouldDelete);
    }

private:
    //==============================================================================
    ScopedPointer<ObjectType> object;
    bool shouldDelete;

    // This is here to avoid people accidentally taking a second owned copy of
    // a scoped pointer, which is almost certainly not what you intended to do!
    // If you hit a problem with this, you probably meant to say
    //  myPointer.setOwned (myScopedPointer.release())
    void setOwned (const ScopedPointer<ObjectType>&) JUCE_DELETED_FUNCTION;
};

} // namespace juce