mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-12 10:49:59 +01:00
Update to OSCPack v1.1
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,9 +23,20 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#include "IpEndpointName.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cstdio>
|
||||
|
||||
#include "NetworkingUtils.h"
|
||||
|
||||
@@ -43,9 +50,9 @@ unsigned long IpEndpointName::GetHostByName( const char *s )
|
||||
void IpEndpointName::AddressAsString( char *s ) const
|
||||
{
|
||||
if( address == ANY_ADDRESS ){
|
||||
sprintf( s, "<any>" );
|
||||
std::sprintf( s, "<any>" );
|
||||
}else{
|
||||
sprintf( s, "%d.%d.%d.%d",
|
||||
std::sprintf( s, "%d.%d.%d.%d",
|
||||
(int)((address >> 24) & 0xFF),
|
||||
(int)((address >> 16) & 0xFF),
|
||||
(int)((address >> 8) & 0xFF),
|
||||
@@ -58,9 +65,9 @@ void IpEndpointName::AddressAndPortAsString( char *s ) const
|
||||
{
|
||||
if( port == ANY_PORT ){
|
||||
if( address == ANY_ADDRESS ){
|
||||
sprintf( s, "<any>:<any>" );
|
||||
std::sprintf( s, "<any>:<any>" );
|
||||
}else{
|
||||
sprintf( s, "%d.%d.%d.%d:<any>",
|
||||
std::sprintf( s, "%d.%d.%d.%d:<any>",
|
||||
(int)((address >> 24) & 0xFF),
|
||||
(int)((address >> 16) & 0xFF),
|
||||
(int)((address >> 8) & 0xFF),
|
||||
@@ -68,9 +75,9 @@ void IpEndpointName::AddressAndPortAsString( char *s ) const
|
||||
}
|
||||
}else{
|
||||
if( address == ANY_ADDRESS ){
|
||||
sprintf( s, "<any>:%d", port );
|
||||
std::sprintf( s, "<any>:%d", port );
|
||||
}else{
|
||||
sprintf( s, "%d.%d.%d.%d:%d",
|
||||
std::sprintf( s, "%d.%d.%d.%d:%d",
|
||||
(int)((address >> 24) & 0xFF),
|
||||
(int)((address >> 16) & 0xFF),
|
||||
(int)((address >> 8) & 0xFF),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,8 +23,19 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDED_IPENDPOINTNAME_H
|
||||
#define INCLUDED_IPENDPOINTNAME_H
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCPACK_IPENDPOINTNAME_H
|
||||
#define INCLUDED_OSCPACK_IPENDPOINTNAME_H
|
||||
|
||||
|
||||
class IpEndpointName{
|
||||
@@ -54,6 +61,8 @@ public:
|
||||
unsigned long address;
|
||||
int port;
|
||||
|
||||
bool IsMulticastAddress() const { return ((address >> 24) & 0xFF) >= 224 && ((address >> 24) & 0xFF) <= 239; }
|
||||
|
||||
enum { ADDRESS_STRING_LENGTH=17 };
|
||||
void AddressAsString( char *s ) const;
|
||||
|
||||
@@ -71,4 +80,4 @@ inline bool operator!=( const IpEndpointName& lhs, const IpEndpointName& rhs )
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
#endif /* INCLUDED_IPENDPOINTNAME_H */
|
||||
#endif /* INCLUDED_OSCPACK_IPENDPOINTNAME_H */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,8 +23,19 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDED_NETWORKINGUTILS_H
|
||||
#define INCLUDED_NETWORKINGUTILS_H
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCPACK_NETWORKINGUTILS_H
|
||||
#define INCLUDED_OSCPACK_NETWORKINGUTILS_H
|
||||
|
||||
|
||||
// in general NetworkInitializer is only used internally, but if you're
|
||||
@@ -46,4 +53,4 @@ public:
|
||||
unsigned long GetHostByName( const char *name );
|
||||
|
||||
|
||||
#endif /* INCLUDED_NETWORKINGUTILS_H */
|
||||
#endif /* INCLUDED_OSCPACK_NETWORKINGUTILS_H */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,8 +23,19 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDED_PACKETLISTENER_H
|
||||
#define INCLUDED_PACKETLISTENER_H
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCPACK_PACKETLISTENER_H
|
||||
#define INCLUDED_OSCPACK_PACKETLISTENER_H
|
||||
|
||||
|
||||
class IpEndpointName;
|
||||
@@ -40,4 +47,4 @@ public:
|
||||
const IpEndpointName& remoteEndpoint ) = 0;
|
||||
};
|
||||
|
||||
#endif /* INCLUDED_PACKETLISTENER_H */
|
||||
#endif /* INCLUDED_OSCPACK_PACKETLISTENER_H */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,8 +23,19 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDED_TIMERLISTENER_H
|
||||
#define INCLUDED_TIMERLISTENER_H
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCPACK_TIMERLISTENER_H
|
||||
#define INCLUDED_OSCPACK_TIMERLISTENER_H
|
||||
|
||||
|
||||
class TimerListener{
|
||||
@@ -37,4 +44,4 @@ public:
|
||||
virtual void TimerExpired() = 0;
|
||||
};
|
||||
|
||||
#endif /* INCLUDED_TIMERLISTENER_H */
|
||||
#endif /* INCLUDED_OSCPACK_TIMERLISTENER_H */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,16 +23,24 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDED_UDPSOCKET_H
|
||||
#define INCLUDED_UDPSOCKET_H
|
||||
|
||||
#ifndef INCLUDED_NETWORKINGUTILITIES_H
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCPACK_UDPSOCKET_H
|
||||
#define INCLUDED_OSCPACK_UDPSOCKET_H
|
||||
|
||||
#include <cstring> // size_t
|
||||
|
||||
#include "NetworkingUtils.h"
|
||||
#endif /* INCLUDED_NETWORKINGUTILITIES_H */
|
||||
|
||||
#ifndef INCLUDED_IPENDPOINTNAME_H
|
||||
#include "IpEndpointName.h"
|
||||
#endif /* INCLUDED_IPENDPOINTNAME_H */
|
||||
|
||||
|
||||
class PacketListener;
|
||||
@@ -80,26 +84,40 @@ class UdpSocket{
|
||||
|
||||
public:
|
||||
|
||||
// ctor throws std::runtime_error if there's a problem
|
||||
// Ctor throws std::runtime_error if there's a problem
|
||||
// initializing the socket.
|
||||
UdpSocket();
|
||||
virtual ~UdpSocket();
|
||||
|
||||
// the socket is created in an unbound, unconnected state
|
||||
// Enable broadcast addresses (e.g. x.x.x.255)
|
||||
// Sets SO_BROADCAST socket option.
|
||||
void SetEnableBroadcast( bool enableBroadcast );
|
||||
|
||||
// Enable multiple listeners for a single port on same
|
||||
// network interface*
|
||||
// Sets SO_REUSEADDR (also SO_REUSEPORT on OS X).
|
||||
// [*] The exact behavior of SO_REUSEADDR and
|
||||
// SO_REUSEPORT is undefined for some common cases
|
||||
// and may have drastically different behavior on different
|
||||
// operating systems.
|
||||
void SetAllowReuse( bool allowReuse );
|
||||
|
||||
|
||||
// The socket is created in an unbound, unconnected state
|
||||
// such a socket can only be used to send to an arbitrary
|
||||
// address using SendTo(). To use Send() you need to first
|
||||
// connect to a remote endpoint using Connect(). To use
|
||||
// ReceiveFrom you need to first bind to a local endpoint
|
||||
// using Bind().
|
||||
|
||||
// retrieve the local endpoint name when sending to 'to'
|
||||
IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const;
|
||||
// Retrieve the local endpoint name when sending to 'to'
|
||||
IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const;
|
||||
|
||||
// Connect to a remote endpoint which is used as the target
|
||||
// for calls to Send()
|
||||
void Connect( const IpEndpointName& remoteEndpoint );
|
||||
void Send( const char *data, int size );
|
||||
void SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size );
|
||||
void Send( const char *data, std::size_t size );
|
||||
void SendTo( const IpEndpointName& remoteEndpoint, const char *data, std::size_t size );
|
||||
|
||||
|
||||
// Bind a local endpoint to receive incoming data. Endpoint
|
||||
@@ -107,7 +125,7 @@ public:
|
||||
void Bind( const IpEndpointName& localEndpoint );
|
||||
bool IsBound() const;
|
||||
|
||||
int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size );
|
||||
std::size_t ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, std::size_t size );
|
||||
};
|
||||
|
||||
|
||||
@@ -155,4 +173,4 @@ public:
|
||||
};
|
||||
|
||||
|
||||
#endif /* INCLUDED_UDPSOCKET_H */
|
||||
#endif /* INCLUDED_OSCPACK_UDPSOCKET_H */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,13 +23,24 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#include "ip/NetworkingUtils.h"
|
||||
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +56,7 @@ unsigned long GetHostByName( const char *name )
|
||||
struct hostent *h = gethostbyname( name );
|
||||
if( h ){
|
||||
struct in_addr a;
|
||||
memcpy( &a, h->h_addr_list[0], h->h_length );
|
||||
std::memcpy( &a, h->h_addr_list[0], h->h_length );
|
||||
result = ntohl(a.s_addr);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,16 +23,18 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "ip/UdpSocket.h"
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
#include <string.h> // for memset
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#include "ip/UdpSocket.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
@@ -48,19 +46,30 @@
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h> // for sockaddr_in
|
||||
|
||||
#include <signal.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring> // for memset
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#include "ip/PacketListener.h"
|
||||
#include "ip/TimerListener.h"
|
||||
|
||||
|
||||
#if defined(__APPLE__) && !defined(_SOCKLEN_T)
|
||||
// pre system 10.3 didn have socklen_t
|
||||
// pre system 10.3 didn't have socklen_t
|
||||
typedef ssize_t socklen_t;
|
||||
#endif
|
||||
|
||||
|
||||
static void SockaddrFromIpEndpointName( struct sockaddr_in& sockAddr, const IpEndpointName& endpoint )
|
||||
{
|
||||
memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
|
||||
std::memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
|
||||
sockAddr.sin_family = AF_INET;
|
||||
|
||||
sockAddr.sin_addr.s_addr =
|
||||
@@ -107,7 +116,7 @@ public:
|
||||
throw std::runtime_error("unable to create udp socket\n");
|
||||
}
|
||||
|
||||
memset( &sendToAddr_, 0, sizeof(sendToAddr_) );
|
||||
std::memset( &sendToAddr_, 0, sizeof(sendToAddr_) );
|
||||
sendToAddr_.sin_family = AF_INET;
|
||||
}
|
||||
|
||||
@@ -116,6 +125,24 @@ public:
|
||||
if (socket_ != -1) close(socket_);
|
||||
}
|
||||
|
||||
void SetEnableBroadcast( bool enableBroadcast )
|
||||
{
|
||||
int broadcast = (enableBroadcast) ? 1 : 0; // int on posix
|
||||
setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
|
||||
}
|
||||
|
||||
void SetAllowReuse( bool allowReuse )
|
||||
{
|
||||
int reuseAddr = (allowReuse) ? 1 : 0; // int on posix
|
||||
setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(reuseAddr));
|
||||
|
||||
#ifdef __APPLE__
|
||||
// needed also for OS X - enable multiple listeners for a single port on same network interface
|
||||
int reusePort = (allowReuse) ? 1 : 0; // int on posix
|
||||
setsockopt(socket_, SOL_SOCKET, SO_REUSEPORT, &reusePort, sizeof(reusePort));
|
||||
#endif
|
||||
}
|
||||
|
||||
IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
|
||||
{
|
||||
assert( isBound_ );
|
||||
@@ -132,7 +159,7 @@ public:
|
||||
// get the address
|
||||
|
||||
struct sockaddr_in sockAddr;
|
||||
memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
|
||||
std::memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
|
||||
socklen_t length = sizeof(sockAddr);
|
||||
if (getsockname(socket_, (struct sockaddr *)&sockAddr, &length) < 0) {
|
||||
throw std::runtime_error("unable to getsockname\n");
|
||||
@@ -149,7 +176,7 @@ public:
|
||||
// unconnect from the remote address
|
||||
|
||||
struct sockaddr_in unconnectSockAddr;
|
||||
memset( (char *)&unconnectSockAddr, 0, sizeof(unconnectSockAddr ) );
|
||||
std::memset( (char *)&unconnectSockAddr, 0, sizeof(unconnectSockAddr ) );
|
||||
unconnectSockAddr.sin_family = AF_UNSPEC;
|
||||
// address fields are zero
|
||||
int connectResult = connect(socket_, (struct sockaddr *)&unconnectSockAddr, sizeof(unconnectSockAddr));
|
||||
@@ -172,14 +199,14 @@ public:
|
||||
isConnected_ = true;
|
||||
}
|
||||
|
||||
void Send( const char *data, int size )
|
||||
void Send( const char *data, std::size_t size )
|
||||
{
|
||||
assert( isConnected_ );
|
||||
|
||||
send( socket_, data, size, 0 );
|
||||
}
|
||||
|
||||
void SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size )
|
||||
void SendTo( const IpEndpointName& remoteEndpoint, const char *data, std::size_t size )
|
||||
{
|
||||
sendToAddr_.sin_addr.s_addr = htonl( remoteEndpoint.address );
|
||||
sendToAddr_.sin_port = htons( remoteEndpoint.port );
|
||||
@@ -201,14 +228,14 @@ public:
|
||||
|
||||
bool IsBound() const { return isBound_; }
|
||||
|
||||
int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size )
|
||||
std::size_t ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, std::size_t size )
|
||||
{
|
||||
assert( isBound_ );
|
||||
|
||||
struct sockaddr_in fromAddr;
|
||||
socklen_t fromAddrLen = sizeof(fromAddr);
|
||||
|
||||
int result = recvfrom(socket_, data, size, 0,
|
||||
ssize_t result = recvfrom(socket_, data, size, 0,
|
||||
(struct sockaddr *) &fromAddr, (socklen_t*)&fromAddrLen);
|
||||
if( result < 0 )
|
||||
return 0;
|
||||
@@ -216,7 +243,7 @@ public:
|
||||
remoteEndpoint.address = ntohl(fromAddr.sin_addr.s_addr);
|
||||
remoteEndpoint.port = ntohs(fromAddr.sin_port);
|
||||
|
||||
return result;
|
||||
return (std::size_t)result;
|
||||
}
|
||||
|
||||
int Socket() { return socket_; }
|
||||
@@ -232,6 +259,16 @@ UdpSocket::~UdpSocket()
|
||||
delete impl_;
|
||||
}
|
||||
|
||||
void UdpSocket::SetEnableBroadcast( bool enableBroadcast )
|
||||
{
|
||||
impl_->SetEnableBroadcast( enableBroadcast );
|
||||
}
|
||||
|
||||
void UdpSocket::SetAllowReuse( bool allowReuse )
|
||||
{
|
||||
impl_->SetAllowReuse( allowReuse );
|
||||
}
|
||||
|
||||
IpEndpointName UdpSocket::LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
|
||||
{
|
||||
return impl_->LocalEndpointFor( remoteEndpoint );
|
||||
@@ -242,12 +279,12 @@ void UdpSocket::Connect( const IpEndpointName& remoteEndpoint )
|
||||
impl_->Connect( remoteEndpoint );
|
||||
}
|
||||
|
||||
void UdpSocket::Send( const char *data, int size )
|
||||
void UdpSocket::Send( const char *data, std::size_t size )
|
||||
{
|
||||
impl_->Send( data, size );
|
||||
}
|
||||
|
||||
void UdpSocket::SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size )
|
||||
void UdpSocket::SendTo( const IpEndpointName& remoteEndpoint, const char *data, std::size_t size )
|
||||
{
|
||||
impl_->SendTo( remoteEndpoint, data, size );
|
||||
}
|
||||
@@ -262,7 +299,7 @@ bool UdpSocket::IsBound() const
|
||||
return impl_->IsBound();
|
||||
}
|
||||
|
||||
int UdpSocket::ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size )
|
||||
std::size_t UdpSocket::ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, std::size_t size )
|
||||
{
|
||||
return impl_->ReceiveFrom( remoteEndpoint, data, size );
|
||||
}
|
||||
@@ -368,104 +405,123 @@ public:
|
||||
void Run()
|
||||
{
|
||||
break_ = false;
|
||||
char *data = 0;
|
||||
|
||||
// configure the master fd_set for select()
|
||||
try{
|
||||
|
||||
fd_set masterfds, tempfds;
|
||||
FD_ZERO( &masterfds );
|
||||
FD_ZERO( &tempfds );
|
||||
// configure the master fd_set for select()
|
||||
|
||||
// in addition to listening to the inbound sockets we
|
||||
// also listen to the asynchronous break pipe, so that AsynchronousBreak()
|
||||
// can break us out of select() from another thread.
|
||||
FD_SET( breakPipe_[0], &masterfds );
|
||||
int fdmax = breakPipe_[0];
|
||||
fd_set masterfds, tempfds;
|
||||
FD_ZERO( &masterfds );
|
||||
FD_ZERO( &tempfds );
|
||||
|
||||
for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
|
||||
i != socketListeners_.end(); ++i ){
|
||||
// in addition to listening to the inbound sockets we
|
||||
// also listen to the asynchronous break pipe, so that AsynchronousBreak()
|
||||
// can break us out of select() from another thread.
|
||||
FD_SET( breakPipe_[0], &masterfds );
|
||||
int fdmax = breakPipe_[0];
|
||||
|
||||
if( fdmax < i->second->impl_->Socket() )
|
||||
fdmax = i->second->impl_->Socket();
|
||||
FD_SET( i->second->impl_->Socket(), &masterfds );
|
||||
}
|
||||
for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
|
||||
i != socketListeners_.end(); ++i ){
|
||||
|
||||
if( fdmax < i->second->impl_->Socket() )
|
||||
fdmax = i->second->impl_->Socket();
|
||||
FD_SET( i->second->impl_->Socket(), &masterfds );
|
||||
}
|
||||
|
||||
|
||||
// configure the timer queue
|
||||
double currentTimeMs = GetCurrentTimeMs();
|
||||
// configure the timer queue
|
||||
double currentTimeMs = GetCurrentTimeMs();
|
||||
|
||||
// expiry time ms, listener
|
||||
std::vector< std::pair< double, AttachedTimerListener > > timerQueue_;
|
||||
for( std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin();
|
||||
i != timerListeners_.end(); ++i )
|
||||
timerQueue_.push_back( std::make_pair( currentTimeMs + i->initialDelayMs, *i ) );
|
||||
std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );
|
||||
// expiry time ms, listener
|
||||
std::vector< std::pair< double, AttachedTimerListener > > timerQueue_;
|
||||
for( std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin();
|
||||
i != timerListeners_.end(); ++i )
|
||||
timerQueue_.push_back( std::make_pair( currentTimeMs + i->initialDelayMs, *i ) );
|
||||
std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );
|
||||
|
||||
const int MAX_BUFFER_SIZE = 4098;
|
||||
char *data = new char[ MAX_BUFFER_SIZE ];
|
||||
IpEndpointName remoteEndpoint;
|
||||
const int MAX_BUFFER_SIZE = 4098;
|
||||
data = new char[ MAX_BUFFER_SIZE ];
|
||||
IpEndpointName remoteEndpoint;
|
||||
|
||||
struct timeval timeout;
|
||||
struct timeval timeout;
|
||||
|
||||
while( !break_ ){
|
||||
tempfds = masterfds;
|
||||
while( !break_ ){
|
||||
tempfds = masterfds;
|
||||
|
||||
struct timeval *timeoutPtr = 0;
|
||||
if( !timerQueue_.empty() ){
|
||||
double timeoutMs = timerQueue_.front().first - GetCurrentTimeMs();
|
||||
if( timeoutMs < 0 )
|
||||
timeoutMs = 0;
|
||||
struct timeval *timeoutPtr = 0;
|
||||
if( !timerQueue_.empty() ){
|
||||
double timeoutMs = timerQueue_.front().first - GetCurrentTimeMs();
|
||||
if( timeoutMs < 0 )
|
||||
timeoutMs = 0;
|
||||
|
||||
// 1000000 microseconds in a second
|
||||
timeout.tv_sec = (long)(timeoutMs * .001);
|
||||
timeout.tv_usec = (long)((timeoutMs - (timeout.tv_sec * 1000)) * 1000);
|
||||
timeoutPtr = &timeout;
|
||||
}
|
||||
long timoutSecondsPart = (long)(timeoutMs * .001);
|
||||
timeout.tv_sec = (time_t)timoutSecondsPart;
|
||||
// 1000000 microseconds in a second
|
||||
timeout.tv_usec = (suseconds_t)((timeoutMs - (timoutSecondsPart * 1000)) * 1000);
|
||||
timeoutPtr = &timeout;
|
||||
}
|
||||
|
||||
if( select( fdmax + 1, &tempfds, 0, 0, timeoutPtr ) < 0 && errno != EINTR ){
|
||||
throw std::runtime_error("select failed\n");
|
||||
}
|
||||
if( select( fdmax + 1, &tempfds, 0, 0, timeoutPtr ) < 0 ){
|
||||
if( break_ ){
|
||||
break;
|
||||
}else if( errno == EINTR ){
|
||||
// on returning an error, select() doesn't clear tempfds.
|
||||
// so tempfds would remain all set, which would cause read( breakPipe_[0]...
|
||||
// below to block indefinitely. therefore if select returns EINTR we restart
|
||||
// the while() loop instead of continuing on to below.
|
||||
continue;
|
||||
}else{
|
||||
throw std::runtime_error("select failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
if ( FD_ISSET( breakPipe_[0], &tempfds ) ){
|
||||
// clear pending data from the asynchronous break pipe
|
||||
char c;
|
||||
read( breakPipe_[0], &c, 1 );
|
||||
}
|
||||
if( FD_ISSET( breakPipe_[0], &tempfds ) ){
|
||||
// clear pending data from the asynchronous break pipe
|
||||
char c;
|
||||
read( breakPipe_[0], &c, 1 );
|
||||
}
|
||||
|
||||
if( break_ )
|
||||
break;
|
||||
if( break_ )
|
||||
break;
|
||||
|
||||
for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
|
||||
i != socketListeners_.end(); ++i ){
|
||||
for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin();
|
||||
i != socketListeners_.end(); ++i ){
|
||||
|
||||
if( FD_ISSET( i->second->impl_->Socket(), &tempfds ) ){
|
||||
if( FD_ISSET( i->second->impl_->Socket(), &tempfds ) ){
|
||||
|
||||
int size = i->second->ReceiveFrom( remoteEndpoint, data, MAX_BUFFER_SIZE );
|
||||
if( size > 0 ){
|
||||
i->first->ProcessPacket( data, size, remoteEndpoint );
|
||||
if( break_ )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::size_t size = i->second->ReceiveFrom( remoteEndpoint, data, MAX_BUFFER_SIZE );
|
||||
if( size > 0 ){
|
||||
i->first->ProcessPacket( data, (int)size, remoteEndpoint );
|
||||
if( break_ )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// execute any expired timers
|
||||
currentTimeMs = GetCurrentTimeMs();
|
||||
bool resort = false;
|
||||
for( std::vector< std::pair< double, AttachedTimerListener > >::iterator i = timerQueue_.begin();
|
||||
i != timerQueue_.end() && i->first <= currentTimeMs; ++i ){
|
||||
// execute any expired timers
|
||||
currentTimeMs = GetCurrentTimeMs();
|
||||
bool resort = false;
|
||||
for( std::vector< std::pair< double, AttachedTimerListener > >::iterator i = timerQueue_.begin();
|
||||
i != timerQueue_.end() && i->first <= currentTimeMs; ++i ){
|
||||
|
||||
i->second.listener->TimerExpired();
|
||||
if( break_ )
|
||||
break;
|
||||
i->second.listener->TimerExpired();
|
||||
if( break_ )
|
||||
break;
|
||||
|
||||
i->first += i->second.periodMs;
|
||||
resort = true;
|
||||
}
|
||||
if( resort )
|
||||
std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );
|
||||
}
|
||||
i->first += i->second.periodMs;
|
||||
resort = true;
|
||||
}
|
||||
if( resort )
|
||||
std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );
|
||||
}
|
||||
|
||||
delete [] data;
|
||||
delete [] data;
|
||||
}catch(...){
|
||||
if( data )
|
||||
delete [] data;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void Break()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,12 +23,23 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#include "ip/NetworkingUtils.h"
|
||||
|
||||
#include <winsock2.h> // this must come first to prevent errors with MSVC7
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
|
||||
static LONG initCount_ = 0;
|
||||
@@ -80,7 +87,7 @@ unsigned long GetHostByName( const char *name )
|
||||
struct hostent *h = gethostbyname( name );
|
||||
if( h ){
|
||||
struct in_addr a;
|
||||
memcpy( &a, h->h_addr_list[0], h->h_length );
|
||||
std::memcpy( &a, h->h_addr_list[0], h->h_length );
|
||||
result = ntohl(a.s_addr);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,17 +23,35 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "ip/UdpSocket.h"
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
|
||||
#include <winsock2.h> // this must come first to prevent errors with MSVC7
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h> // for timeGetTime()
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <assert.h>
|
||||
#ifndef WINCE
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring> // for memset
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#include "ip/UdpSocket.h" // usually I'd include the module header first
|
||||
// but this is causing conflicts with BCB4 due to
|
||||
// std::size_t usage.
|
||||
|
||||
#include "ip/NetworkingUtils.h"
|
||||
#include "ip/PacketListener.h"
|
||||
@@ -49,7 +63,7 @@ typedef int socklen_t;
|
||||
|
||||
static void SockaddrFromIpEndpointName( struct sockaddr_in& sockAddr, const IpEndpointName& endpoint )
|
||||
{
|
||||
memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
|
||||
std::memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
|
||||
sockAddr.sin_family = AF_INET;
|
||||
|
||||
sockAddr.sin_addr.s_addr =
|
||||
@@ -98,7 +112,7 @@ public:
|
||||
throw std::runtime_error("unable to create udp socket\n");
|
||||
}
|
||||
|
||||
memset( &sendToAddr_, 0, sizeof(sendToAddr_) );
|
||||
std::memset( &sendToAddr_, 0, sizeof(sendToAddr_) );
|
||||
sendToAddr_.sin_family = AF_INET;
|
||||
}
|
||||
|
||||
@@ -107,6 +121,22 @@ public:
|
||||
if (socket_ != INVALID_SOCKET) closesocket(socket_);
|
||||
}
|
||||
|
||||
void SetEnableBroadcast( bool enableBroadcast )
|
||||
{
|
||||
char broadcast = (char)((enableBroadcast) ? 1 : 0); // char on win32
|
||||
setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
|
||||
}
|
||||
|
||||
void SetAllowReuse( bool allowReuse )
|
||||
{
|
||||
// Note: SO_REUSEADDR is non-deterministic for listening sockets on Win32. See MSDN article:
|
||||
// "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE"
|
||||
// http://msdn.microsoft.com/en-us/library/ms740621%28VS.85%29.aspx
|
||||
|
||||
char reuseAddr = (char)((allowReuse) ? 1 : 0); // char on win32
|
||||
setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(reuseAddr));
|
||||
}
|
||||
|
||||
IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
|
||||
{
|
||||
assert( isBound_ );
|
||||
@@ -123,7 +153,7 @@ public:
|
||||
// get the address
|
||||
|
||||
struct sockaddr_in sockAddr;
|
||||
memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
|
||||
std::memset( (char *)&sockAddr, 0, sizeof(sockAddr ) );
|
||||
socklen_t length = sizeof(sockAddr);
|
||||
if (getsockname(socket_, (struct sockaddr *)&sockAddr, &length) < 0) {
|
||||
throw std::runtime_error("unable to getsockname\n");
|
||||
@@ -162,19 +192,19 @@ public:
|
||||
isConnected_ = true;
|
||||
}
|
||||
|
||||
void Send( const char *data, int size )
|
||||
void Send( const char *data, std::size_t size )
|
||||
{
|
||||
assert( isConnected_ );
|
||||
|
||||
send( socket_, data, size, 0 );
|
||||
send( socket_, data, (int)size, 0 );
|
||||
}
|
||||
|
||||
void SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size )
|
||||
void SendTo( const IpEndpointName& remoteEndpoint, const char *data, std::size_t size )
|
||||
{
|
||||
sendToAddr_.sin_addr.s_addr = htonl( remoteEndpoint.address );
|
||||
sendToAddr_.sin_port = htons( (short)remoteEndpoint.port );
|
||||
|
||||
sendto( socket_, data, size, 0, (sockaddr*)&sendToAddr_, sizeof(sendToAddr_) );
|
||||
sendto( socket_, data, (int)size, 0, (sockaddr*)&sendToAddr_, sizeof(sendToAddr_) );
|
||||
}
|
||||
|
||||
void Bind( const IpEndpointName& localEndpoint )
|
||||
@@ -191,14 +221,14 @@ public:
|
||||
|
||||
bool IsBound() const { return isBound_; }
|
||||
|
||||
int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size )
|
||||
std::size_t ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, std::size_t size )
|
||||
{
|
||||
assert( isBound_ );
|
||||
|
||||
struct sockaddr_in fromAddr;
|
||||
socklen_t fromAddrLen = sizeof(fromAddr);
|
||||
|
||||
int result = recvfrom(socket_, data, size, 0,
|
||||
int result = recvfrom(socket_, data, (int)size, 0,
|
||||
(struct sockaddr *) &fromAddr, (socklen_t*)&fromAddrLen);
|
||||
if( result < 0 )
|
||||
return 0;
|
||||
@@ -222,6 +252,16 @@ UdpSocket::~UdpSocket()
|
||||
delete impl_;
|
||||
}
|
||||
|
||||
void UdpSocket::SetEnableBroadcast( bool enableBroadcast )
|
||||
{
|
||||
impl_->SetEnableBroadcast( enableBroadcast );
|
||||
}
|
||||
|
||||
void UdpSocket::SetAllowReuse( bool allowReuse )
|
||||
{
|
||||
impl_->SetAllowReuse( allowReuse );
|
||||
}
|
||||
|
||||
IpEndpointName UdpSocket::LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const
|
||||
{
|
||||
return impl_->LocalEndpointFor( remoteEndpoint );
|
||||
@@ -232,12 +272,12 @@ void UdpSocket::Connect( const IpEndpointName& remoteEndpoint )
|
||||
impl_->Connect( remoteEndpoint );
|
||||
}
|
||||
|
||||
void UdpSocket::Send( const char *data, int size )
|
||||
void UdpSocket::Send( const char *data, std::size_t size )
|
||||
{
|
||||
impl_->Send( data, size );
|
||||
}
|
||||
|
||||
void UdpSocket::SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size )
|
||||
void UdpSocket::SendTo( const IpEndpointName& remoteEndpoint, const char *data, std::size_t size )
|
||||
{
|
||||
impl_->SendTo( remoteEndpoint, data, size );
|
||||
}
|
||||
@@ -252,7 +292,7 @@ bool UdpSocket::IsBound() const
|
||||
return impl_->IsBound();
|
||||
}
|
||||
|
||||
int UdpSocket::ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size )
|
||||
std::size_t UdpSocket::ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, std::size_t size )
|
||||
{
|
||||
return impl_->ReceiveFrom( remoteEndpoint, data, size );
|
||||
}
|
||||
@@ -282,7 +322,9 @@ extern "C" /*static*/ void InterruptSignalHandler( int );
|
||||
/*static*/ void InterruptSignalHandler( int )
|
||||
{
|
||||
multiplexerInstanceToAbortWithSigInt_->AsynchronousBreak();
|
||||
signal( SIGINT, SIG_DFL );
|
||||
#ifndef WINCE
|
||||
signal( SIGINT, SIG_DFL );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -297,8 +339,12 @@ class SocketReceiveMultiplexer::Implementation{
|
||||
|
||||
double GetCurrentTimeMs() const
|
||||
{
|
||||
#ifndef WINCE
|
||||
return timeGetTime(); // FIXME: bad choice if you want to run for more than 40 days
|
||||
}
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
Implementation()
|
||||
@@ -405,9 +451,9 @@ public:
|
||||
|
||||
if( waitResult != WAIT_TIMEOUT ){
|
||||
for( int i = waitResult - WAIT_OBJECT_0; i < (int)socketListeners_.size(); ++i ){
|
||||
int size = socketListeners_[i].second->ReceiveFrom( remoteEndpoint, data, MAX_BUFFER_SIZE );
|
||||
std::size_t size = socketListeners_[i].second->ReceiveFrom( remoteEndpoint, data, MAX_BUFFER_SIZE );
|
||||
if( size > 0 ){
|
||||
socketListeners_[i].first->ProcessPacket( data, size, remoteEndpoint );
|
||||
socketListeners_[i].first->ProcessPacket( data, (int)size, remoteEndpoint );
|
||||
if( break_ )
|
||||
break;
|
||||
}
|
||||
@@ -503,9 +549,13 @@ void SocketReceiveMultiplexer::RunUntilSigInt()
|
||||
{
|
||||
assert( multiplexerInstanceToAbortWithSigInt_ == 0 ); /* at present we support only one multiplexer instance running until sig int */
|
||||
multiplexerInstanceToAbortWithSigInt_ = this;
|
||||
signal( SIGINT, InterruptSignalHandler );
|
||||
#ifndef WINCE
|
||||
signal( SIGINT, InterruptSignalHandler );
|
||||
#endif
|
||||
impl_->Run();
|
||||
#ifndef WINCE
|
||||
signal( SIGINT, SIG_DFL );
|
||||
#endif
|
||||
multiplexerInstanceToAbortWithSigInt_ = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,10 +23,21 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDED_MESSAGEMAPPINGOSCPACKETLISTENER_H
|
||||
#define INCLUDED_MESSAGEMAPPINGOSCPACKETLISTENER_H
|
||||
|
||||
#include <string.h>
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCPACK_MESSAGEMAPPINGOSCPACKETLISTENER_H
|
||||
#define INCLUDED_OSCPACK_MESSAGEMAPPINGOSCPACKETLISTENER_H
|
||||
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
|
||||
#include "OscPacketListener.h"
|
||||
@@ -61,7 +68,7 @@ protected:
|
||||
private:
|
||||
struct cstr_compare{
|
||||
bool operator()( const char *lhs, const char *rhs ) const
|
||||
{ return strcmp( lhs, rhs ) < 0; }
|
||||
{ return std::strcmp( lhs, rhs ) < 0; }
|
||||
};
|
||||
|
||||
typedef std::map<const char*, function_type, cstr_compare> function_map_type;
|
||||
@@ -70,4 +77,4 @@ private:
|
||||
|
||||
} // namespace osc
|
||||
|
||||
#endif /* INCLUDED_MESSAGEMAPPINGOSCPACKETLISTENER_H */
|
||||
#endif /* INCLUDED_OSCPACK_MESSAGEMAPPINGOSCPACKETLISTENER_H */
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,8 +23,19 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDED_OSC_EXCEPTION_H
|
||||
#define INCLUDED_OSC_EXCEPTION_H
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCPACK_OSCEXCEPTION_H
|
||||
#define INCLUDED_OSCPACK_OSCEXCEPTION_H
|
||||
|
||||
#include <exception>
|
||||
|
||||
@@ -40,7 +47,8 @@ class Exception : public std::exception {
|
||||
public:
|
||||
Exception() throw() {}
|
||||
Exception( const Exception& src ) throw()
|
||||
: what_( src.what_ ) {}
|
||||
: std::exception( src )
|
||||
, what_( src.what_ ) {}
|
||||
Exception( const char *w ) throw()
|
||||
: what_( w ) {}
|
||||
Exception& operator=( const Exception& src ) throw()
|
||||
@@ -51,4 +59,4 @@ public:
|
||||
|
||||
} // namespace osc
|
||||
|
||||
#endif /* INCLUDED_OSC_EXCEPTION_H */
|
||||
#endif /* INCLUDED_OSCPACK_OSCEXCEPTION_H */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,18 +23,37 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#include "OscOutboundPacketStream.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(__WIN32__) || defined(WIN32)
|
||||
#if defined(__WIN32__) || defined(WIN32) || defined(_WIN32)
|
||||
#include <malloc.h> // for alloca
|
||||
#else
|
||||
//#include <alloca.h> // alloca on Linux (also OSX)
|
||||
#include <stdlib.h> // alloca on OSX and FreeBSD (and Linux?)
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring> // memcpy, memmove, strcpy, strlen
|
||||
#include <cstddef> // ptrdiff_t
|
||||
|
||||
#include "OscHostEndianness.h"
|
||||
|
||||
#if defined(__BORLANDC__) // workaround for BCB4 release build intrinsics bug
|
||||
namespace std {
|
||||
using ::__strcpy__; // avoid error: E2316 '__strcpy__' is not a member of 'std'.
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace osc{
|
||||
|
||||
@@ -130,13 +145,14 @@ static void FromUInt64( char *p, uint64 x )
|
||||
}
|
||||
|
||||
|
||||
static inline long RoundUp4( long x )
|
||||
// round up to the next highest multiple of 4. unless x is already a multiple of 4
|
||||
static inline std::size_t RoundUp4( std::size_t x )
|
||||
{
|
||||
return ((x-1) & (~0x03L)) + 4;
|
||||
return (x + 3) & ~((std::size_t)0x03);
|
||||
}
|
||||
|
||||
|
||||
OutboundPacketStream::OutboundPacketStream( char *buffer, unsigned long capacity )
|
||||
OutboundPacketStream::OutboundPacketStream( char *buffer, std::size_t capacity )
|
||||
: data_( buffer )
|
||||
, end_( data_ + capacity )
|
||||
, typeTagsCurrent_( end_ )
|
||||
@@ -145,7 +161,12 @@ OutboundPacketStream::OutboundPacketStream( char *buffer, unsigned long capacity
|
||||
, elementSizePtr_( 0 )
|
||||
, messageIsInProgress_( false )
|
||||
{
|
||||
|
||||
// sanity check integer types declared in OscTypes.h
|
||||
// you'll need to fix OscTypes.h if any of these asserts fail
|
||||
assert( sizeof(osc::int32) == 4 );
|
||||
assert( sizeof(osc::uint32) == 4 );
|
||||
assert( sizeof(osc::int64) == 8 );
|
||||
assert( sizeof(osc::uint64) == 8 );
|
||||
}
|
||||
|
||||
|
||||
@@ -189,12 +210,15 @@ void OutboundPacketStream::EndElement( char *endPtr )
|
||||
// size slot is stored in the elements size slot (or a ptr to data_
|
||||
// if there is no containing element). We retrieve that here
|
||||
uint32 *previousElementSizePtr =
|
||||
(uint32*)(data_ + *reinterpret_cast<uint32*>(elementSizePtr_));
|
||||
reinterpret_cast<uint32*>(data_ + *elementSizePtr_);
|
||||
|
||||
// then we store the element size in the slot, note that the element
|
||||
// then we store the element size in the slot. note that the element
|
||||
// size does not include the size slot, hence the - 4 below.
|
||||
uint32 elementSize =
|
||||
(endPtr - reinterpret_cast<char*>(elementSizePtr_)) - 4;
|
||||
|
||||
std::ptrdiff_t d = endPtr - reinterpret_cast<char*>(elementSizePtr_);
|
||||
// assert( d >= 4 && d <= 0x7FFFFFFF ); // assume packets smaller than 2Gb
|
||||
|
||||
uint32 elementSize = static_cast<uint32>(d - 4);
|
||||
FromUInt32( reinterpret_cast<char*>(elementSizePtr_), elementSize );
|
||||
|
||||
// finally, we reset the element size ptr to the containing element
|
||||
@@ -211,7 +235,7 @@ bool OutboundPacketStream::ElementSizeSlotRequired() const
|
||||
|
||||
void OutboundPacketStream::CheckForAvailableBundleSpace()
|
||||
{
|
||||
unsigned long required = Size() + ((ElementSizeSlotRequired())?4:0) + 16;
|
||||
std::size_t required = Size() + ((ElementSizeSlotRequired())?4:0) + 16;
|
||||
|
||||
if( required > Capacity() )
|
||||
throw OutOfBufferMemoryException();
|
||||
@@ -221,18 +245,18 @@ void OutboundPacketStream::CheckForAvailableBundleSpace()
|
||||
void OutboundPacketStream::CheckForAvailableMessageSpace( const char *addressPattern )
|
||||
{
|
||||
// plus 4 for at least four bytes of type tag
|
||||
unsigned long required = Size() + ((ElementSizeSlotRequired())?4:0)
|
||||
+ RoundUp4(strlen(addressPattern) + 1) + 4;
|
||||
std::size_t required = Size() + ((ElementSizeSlotRequired())?4:0)
|
||||
+ RoundUp4(std::strlen(addressPattern) + 1) + 4;
|
||||
|
||||
if( required > Capacity() )
|
||||
throw OutOfBufferMemoryException();
|
||||
}
|
||||
|
||||
|
||||
void OutboundPacketStream::CheckForAvailableArgumentSpace( long argumentLength )
|
||||
void OutboundPacketStream::CheckForAvailableArgumentSpace( std::size_t argumentLength )
|
||||
{
|
||||
// plus three for extra type tag, comma and null terminator
|
||||
unsigned long required = (argumentCurrent_ - data_) + argumentLength
|
||||
std::size_t required = (argumentCurrent_ - data_) + argumentLength
|
||||
+ RoundUp4( (end_ - typeTagsCurrent_) + 3 );
|
||||
|
||||
if( required > Capacity() )
|
||||
@@ -250,15 +274,15 @@ void OutboundPacketStream::Clear()
|
||||
}
|
||||
|
||||
|
||||
unsigned int OutboundPacketStream::Capacity() const
|
||||
std::size_t OutboundPacketStream::Capacity() const
|
||||
{
|
||||
return end_ - data_;
|
||||
}
|
||||
|
||||
|
||||
unsigned int OutboundPacketStream::Size() const
|
||||
std::size_t OutboundPacketStream::Size() const
|
||||
{
|
||||
unsigned int result = argumentCurrent_ - data_;
|
||||
std::size_t result = argumentCurrent_ - data_;
|
||||
if( IsMessageInProgress() ){
|
||||
// account for the length of the type tag string. the total type tag
|
||||
// includes an initial comma, plus at least one terminating \0
|
||||
@@ -302,7 +326,7 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const BundleInitiator& r
|
||||
|
||||
messageCursor_ = BeginElement( messageCursor_ );
|
||||
|
||||
memcpy( messageCursor_, "#bundle\0", 8 );
|
||||
std::memcpy( messageCursor_, "#bundle\0", 8 );
|
||||
FromUInt64( messageCursor_ + 8, rhs.timeTag );
|
||||
|
||||
messageCursor_ += 16;
|
||||
@@ -336,12 +360,12 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const BeginMessage& rhs
|
||||
|
||||
messageCursor_ = BeginElement( messageCursor_ );
|
||||
|
||||
strcpy( messageCursor_, rhs.addressPattern );
|
||||
unsigned long rhsLength = strlen(rhs.addressPattern);
|
||||
std::strcpy( messageCursor_, rhs.addressPattern );
|
||||
std::size_t rhsLength = std::strlen(rhs.addressPattern);
|
||||
messageCursor_ += rhsLength + 1;
|
||||
|
||||
// zero pad to 4-byte boundary
|
||||
unsigned long i = rhsLength + 1;
|
||||
std::size_t i = rhsLength + 1;
|
||||
while( i & 0x3 ){
|
||||
*messageCursor_++ = '\0';
|
||||
++i;
|
||||
@@ -363,27 +387,27 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const MessageTerminator&
|
||||
if( !IsMessageInProgress() )
|
||||
throw MessageNotInProgressException();
|
||||
|
||||
int typeTagsCount = end_ - typeTagsCurrent_;
|
||||
std::size_t typeTagsCount = end_ - typeTagsCurrent_;
|
||||
|
||||
if( typeTagsCount ){
|
||||
|
||||
char *tempTypeTags = (char*)alloca(typeTagsCount);
|
||||
memcpy( tempTypeTags, typeTagsCurrent_, typeTagsCount );
|
||||
std::memcpy( tempTypeTags, typeTagsCurrent_, typeTagsCount );
|
||||
|
||||
// slot size includes comma and null terminator
|
||||
int typeTagSlotSize = RoundUp4( typeTagsCount + 2 );
|
||||
std::size_t typeTagSlotSize = RoundUp4( typeTagsCount + 2 );
|
||||
|
||||
uint32 argumentsSize = argumentCurrent_ - messageCursor_;
|
||||
std::size_t argumentsSize = argumentCurrent_ - messageCursor_;
|
||||
|
||||
memmove( messageCursor_ + typeTagSlotSize, messageCursor_, argumentsSize );
|
||||
std::memmove( messageCursor_ + typeTagSlotSize, messageCursor_, argumentsSize );
|
||||
|
||||
messageCursor_[0] = ',';
|
||||
// copy type tags in reverse (really forward) order
|
||||
for( int i=0; i < typeTagsCount; ++i )
|
||||
for( std::size_t i=0; i < typeTagsCount; ++i )
|
||||
messageCursor_[i+1] = tempTypeTags[ (typeTagsCount-1) - i ];
|
||||
|
||||
char *p = messageCursor_ + 1 + typeTagsCount;
|
||||
for( int i=0; i < (typeTagSlotSize - (typeTagsCount + 1)); ++i )
|
||||
for( std::size_t i=0; i < (typeTagSlotSize - (typeTagsCount + 1)); ++i )
|
||||
*p++ = '\0';
|
||||
|
||||
typeTagsCurrent_ = end_;
|
||||
@@ -393,7 +417,7 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const MessageTerminator&
|
||||
|
||||
}else{
|
||||
// send an empty type tags string
|
||||
memcpy( messageCursor_, ",\0\0\0", 4 );
|
||||
std::memcpy( messageCursor_, ",\0\0\0", 4 );
|
||||
|
||||
// advance messageCursor_ for next message
|
||||
messageCursor_ += 4;
|
||||
@@ -575,15 +599,15 @@ OutboundPacketStream& OutboundPacketStream::operator<<( double rhs )
|
||||
|
||||
OutboundPacketStream& OutboundPacketStream::operator<<( const char *rhs )
|
||||
{
|
||||
CheckForAvailableArgumentSpace( RoundUp4(strlen(rhs) + 1) );
|
||||
CheckForAvailableArgumentSpace( RoundUp4(std::strlen(rhs) + 1) );
|
||||
|
||||
*(--typeTagsCurrent_) = STRING_TYPE_TAG;
|
||||
strcpy( argumentCurrent_, rhs );
|
||||
unsigned long rhsLength = strlen(rhs);
|
||||
std::strcpy( argumentCurrent_, rhs );
|
||||
std::size_t rhsLength = std::strlen(rhs);
|
||||
argumentCurrent_ += rhsLength + 1;
|
||||
|
||||
// zero pad to 4-byte boundary
|
||||
unsigned long i = rhsLength + 1;
|
||||
std::size_t i = rhsLength + 1;
|
||||
while( i & 0x3 ){
|
||||
*argumentCurrent_++ = '\0';
|
||||
++i;
|
||||
@@ -595,15 +619,15 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const char *rhs )
|
||||
|
||||
OutboundPacketStream& OutboundPacketStream::operator<<( const Symbol& rhs )
|
||||
{
|
||||
CheckForAvailableArgumentSpace( RoundUp4(strlen(rhs) + 1) );
|
||||
CheckForAvailableArgumentSpace( RoundUp4(std::strlen(rhs) + 1) );
|
||||
|
||||
*(--typeTagsCurrent_) = SYMBOL_TYPE_TAG;
|
||||
strcpy( argumentCurrent_, rhs );
|
||||
unsigned long rhsLength = strlen(rhs);
|
||||
std::strcpy( argumentCurrent_, rhs );
|
||||
std::size_t rhsLength = std::strlen(rhs);
|
||||
argumentCurrent_ += rhsLength + 1;
|
||||
|
||||
// zero pad to 4-byte boundary
|
||||
unsigned long i = rhsLength + 1;
|
||||
std::size_t i = rhsLength + 1;
|
||||
while( i & 0x3 ){
|
||||
*argumentCurrent_++ = '\0';
|
||||
++i;
|
||||
@@ -621,7 +645,7 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const Blob& rhs )
|
||||
FromUInt32( argumentCurrent_, rhs.size );
|
||||
argumentCurrent_ += 4;
|
||||
|
||||
memcpy( argumentCurrent_, rhs.data, rhs.size );
|
||||
std::memcpy( argumentCurrent_, rhs.data, rhs.size );
|
||||
argumentCurrent_ += rhs.size;
|
||||
|
||||
// zero pad to 4-byte boundary
|
||||
@@ -634,6 +658,26 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const Blob& rhs )
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutboundPacketStream& OutboundPacketStream::operator<<( const ArrayInitiator& rhs )
|
||||
{
|
||||
(void) rhs;
|
||||
CheckForAvailableArgumentSpace(0);
|
||||
|
||||
*(--typeTagsCurrent_) = ARRAY_BEGIN_TYPE_TAG;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutboundPacketStream& OutboundPacketStream::operator<<( const ArrayTerminator& rhs )
|
||||
{
|
||||
(void) rhs;
|
||||
CheckForAvailableArgumentSpace(0);
|
||||
|
||||
*(--typeTagsCurrent_) = ARRAY_END_TYPE_TAG;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace osc
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,8 +23,21 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCOUTBOUNDPACKET_H
|
||||
#define INCLUDED_OSCOUTBOUNDPACKET_H
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCPACK_OSCOUTBOUNDPACKETSTREAM_H
|
||||
#define INCLUDED_OSCPACK_OSCOUTBOUNDPACKETSTREAM_H
|
||||
|
||||
#include <cstring> // size_t
|
||||
|
||||
#include "OscTypes.h"
|
||||
#include "OscException.h"
|
||||
@@ -66,15 +75,15 @@ public:
|
||||
|
||||
class OutboundPacketStream{
|
||||
public:
|
||||
OutboundPacketStream( char *buffer, unsigned long capacity );
|
||||
OutboundPacketStream( char *buffer, std::size_t capacity );
|
||||
~OutboundPacketStream();
|
||||
|
||||
void Clear();
|
||||
|
||||
unsigned int Capacity() const;
|
||||
std::size_t Capacity() const;
|
||||
|
||||
// invariant: size() is valid even while building a message.
|
||||
unsigned int Size() const;
|
||||
std::size_t Size() const;
|
||||
|
||||
const char *Data() const;
|
||||
|
||||
@@ -96,7 +105,7 @@ public:
|
||||
OutboundPacketStream& operator<<( const InfinitumType& rhs );
|
||||
OutboundPacketStream& operator<<( int32 rhs );
|
||||
|
||||
#ifndef x86_64
|
||||
#if !(defined(__x86_64__) || defined(_M_X64))
|
||||
OutboundPacketStream& operator<<( int rhs )
|
||||
{ *this << (int32)rhs; return *this; }
|
||||
#endif
|
||||
@@ -112,6 +121,9 @@ public:
|
||||
OutboundPacketStream& operator<<( const Symbol& rhs );
|
||||
OutboundPacketStream& operator<<( const Blob& rhs );
|
||||
|
||||
OutboundPacketStream& operator<<( const ArrayInitiator& rhs );
|
||||
OutboundPacketStream& operator<<( const ArrayTerminator& rhs );
|
||||
|
||||
private:
|
||||
|
||||
char *BeginElement( char *beginPtr );
|
||||
@@ -120,7 +132,7 @@ private:
|
||||
bool ElementSizeSlotRequired() const;
|
||||
void CheckForAvailableBundleSpace();
|
||||
void CheckForAvailableMessageSpace( const char *addressPattern );
|
||||
void CheckForAvailableArgumentSpace( long argumentLength );
|
||||
void CheckForAvailableArgumentSpace( std::size_t argumentLength );
|
||||
|
||||
char *data_;
|
||||
char *end_;
|
||||
@@ -139,4 +151,4 @@ private:
|
||||
|
||||
} // namespace osc
|
||||
|
||||
#endif /* INCLUDED_OSC_OUTBOUND_PACKET_H */
|
||||
#endif /* INCLUDED_OSCPACK_OSCOUTBOUNDPACKETSTREAM_H */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,8 +23,19 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCPACKETLISTENER_H
|
||||
#define INCLUDED_OSCPACKETLISTENER_H
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCPACK_OSCPACKETLISTENER_H
|
||||
#define INCLUDED_OSCPACK_OSCPACKETLISTENER_H
|
||||
|
||||
#include "OscReceivedElements.h"
|
||||
#include "../ip/PacketListener.h"
|
||||
@@ -69,4 +76,4 @@ public:
|
||||
|
||||
} // namespace osc
|
||||
|
||||
#endif /* INCLUDED_OSCPACKETLISTENER_H */
|
||||
#endif /* INCLUDED_OSCPACK_OSCPACKETLISTENER_H */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,13 +23,29 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#include "OscPrintReceivedElements.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined(__BORLANDC__) // workaround for BCB4 release build intrinsics bug
|
||||
namespace std {
|
||||
using ::__strcpy__; // avoid error: E2316 '__strcpy__' is not a member of 'std'.
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace osc{
|
||||
|
||||
@@ -109,20 +121,17 @@ std::ostream& operator<<( std::ostream & os,
|
||||
|
||||
case TIME_TAG_TYPE_TAG:
|
||||
{
|
||||
os << "OSC-timetag:" << arg.AsTimeTagUnchecked();
|
||||
os << "OSC-timetag:" << arg.AsTimeTagUnchecked() << " ";
|
||||
|
||||
std::time_t t =
|
||||
(unsigned long)( arg.AsTimeTagUnchecked() >> 32 );
|
||||
|
||||
// strip trailing newline from string returned by ctime
|
||||
const char *timeString = std::ctime( &t );
|
||||
size_t len = strlen( timeString );
|
||||
char *s = new char[ len + 1 ];
|
||||
strcpy( s, timeString );
|
||||
if( len )
|
||||
s[ len - 1 ] = '\0';
|
||||
size_t len = std::strlen( timeString );
|
||||
|
||||
os << " " << s;
|
||||
// -1 to omit trailing newline from string returned by ctime()
|
||||
if( len > 1 )
|
||||
os.write( timeString, len - 1 );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -140,12 +149,12 @@ std::ostream& operator<<( std::ostream & os,
|
||||
|
||||
case BLOB_TYPE_TAG:
|
||||
{
|
||||
unsigned long size;
|
||||
const void *data;
|
||||
osc_bundle_element_size_t size;
|
||||
arg.AsBlobUnchecked( data, size );
|
||||
os << "OSC-blob:<<" << std::hex << std::setfill('0');
|
||||
unsigned char *p = (unsigned char*)data;
|
||||
for( unsigned long i = 0; i < size; ++i ){
|
||||
for( osc_bundle_element_size_t i = 0; i < size; ++i ){
|
||||
os << "0x" << std::setw(2) << int(p[i]);
|
||||
if( i != size-1 )
|
||||
os << ' ';
|
||||
@@ -155,6 +164,14 @@ std::ostream& operator<<( std::ostream & os,
|
||||
}
|
||||
break;
|
||||
|
||||
case ARRAY_BEGIN_TYPE_TAG:
|
||||
os << "[";
|
||||
break;
|
||||
|
||||
case ARRAY_END_TYPE_TAG:
|
||||
os << "]";
|
||||
break;
|
||||
|
||||
default:
|
||||
os << "unknown";
|
||||
}
|
||||
@@ -165,10 +182,13 @@ std::ostream& operator<<( std::ostream & os,
|
||||
|
||||
std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m )
|
||||
{
|
||||
os << "[";
|
||||
if( m.AddressPatternIsUInt32() )
|
||||
os << m.AddressPatternAsUInt32();
|
||||
else
|
||||
os << m.AddressPattern();
|
||||
|
||||
os << "[" << m.AddressPattern();
|
||||
bool first = true;
|
||||
|
||||
for( ReceivedMessage::const_iterator i = m.ArgumentsBegin();
|
||||
i != m.ArgumentsEnd(); ++i ){
|
||||
if( first ){
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,14 +23,23 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCPRINTRECEIVEDELEMENTS_H
|
||||
#define INCLUDED_OSCPRINTRECEIVEDELEMENTS_H
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCPACK_OSCPRINTRECEIVEDELEMENTS_H
|
||||
#define INCLUDED_OSCPACK_OSCPRINTRECEIVEDELEMENTS_H
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
#ifndef INCLUDED_OSCRECEIVEDELEMENTS_H
|
||||
#include "OscReceivedElements.h"
|
||||
#endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */
|
||||
|
||||
|
||||
namespace osc{
|
||||
@@ -46,4 +51,4 @@ std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b );
|
||||
|
||||
} // namespace osc
|
||||
|
||||
#endif /* INCLUDED_OSCPRINTRECEIVEDELEMENTS_H */
|
||||
#endif /* INCLUDED_OSCPACK_OSCPRINTRECEIVEDELEMENTS_H */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,12 +23,22 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "OscReceivedElements.h"
|
||||
|
||||
#include <cassert>
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#include "OscReceivedElements.h"
|
||||
|
||||
#include "OscHostEndianness.h"
|
||||
|
||||
#include <cstddef> // ptrdiff_t
|
||||
|
||||
namespace osc{
|
||||
|
||||
@@ -77,13 +83,10 @@ static inline const char* FindStr4End( const char *p, const char *end )
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned long RoundUp4( unsigned long x )
|
||||
// round up to the next highest multiple of 4. unless x is already a multiple of 4
|
||||
static inline uint32 RoundUp4( uint32 x )
|
||||
{
|
||||
unsigned long remainder = x & 0x3UL;
|
||||
if( remainder )
|
||||
return x + (4 - remainder);
|
||||
else
|
||||
return x;
|
||||
return (x + 3) & ~((uint32)0x03);
|
||||
}
|
||||
|
||||
|
||||
@@ -127,12 +130,12 @@ static inline uint32 ToUInt32( const char *p )
|
||||
}
|
||||
|
||||
|
||||
int64 ToInt64( const char *p )
|
||||
static inline int64 ToInt64( const char *p )
|
||||
{
|
||||
#ifdef OSC_HOST_LITTLE_ENDIAN
|
||||
union{
|
||||
osc::int64 i;
|
||||
char c[4];
|
||||
char c[8];
|
||||
} u;
|
||||
|
||||
u.c[0] = p[7];
|
||||
@@ -151,12 +154,12 @@ int64 ToInt64( const char *p )
|
||||
}
|
||||
|
||||
|
||||
uint64 ToUInt64( const char *p )
|
||||
static inline uint64 ToUInt64( const char *p )
|
||||
{
|
||||
#ifdef OSC_HOST_LITTLE_ENDIAN
|
||||
union{
|
||||
osc::uint64 i;
|
||||
char c[4];
|
||||
char c[8];
|
||||
} u;
|
||||
|
||||
u.c[0] = p[7];
|
||||
@@ -189,20 +192,20 @@ bool ReceivedBundleElement::IsBundle() const
|
||||
}
|
||||
|
||||
|
||||
int32 ReceivedBundleElement::Size() const
|
||||
osc_bundle_element_size_t ReceivedBundleElement::Size() const
|
||||
{
|
||||
return ToUInt32( size_ );
|
||||
return ToInt32( sizePtr_ );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool ReceivedMessageArgument::AsBool() const
|
||||
{
|
||||
if( !typeTag_ )
|
||||
if( !typeTagPtr_ )
|
||||
throw MissingArgumentException();
|
||||
else if( *typeTag_ == TRUE_TYPE_TAG )
|
||||
else if( *typeTagPtr_ == TRUE_TYPE_TAG )
|
||||
return true;
|
||||
else if( *typeTag_ == FALSE_TYPE_TAG )
|
||||
else if( *typeTagPtr_ == FALSE_TYPE_TAG )
|
||||
return false;
|
||||
else
|
||||
throw WrongArgumentTypeException();
|
||||
@@ -211,9 +214,9 @@ bool ReceivedMessageArgument::AsBool() const
|
||||
|
||||
bool ReceivedMessageArgument::AsBoolUnchecked() const
|
||||
{
|
||||
if( !typeTag_ )
|
||||
if( !typeTagPtr_ )
|
||||
throw MissingArgumentException();
|
||||
else if( *typeTag_ == TRUE_TYPE_TAG )
|
||||
else if( *typeTagPtr_ == TRUE_TYPE_TAG )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@@ -222,9 +225,9 @@ bool ReceivedMessageArgument::AsBoolUnchecked() const
|
||||
|
||||
int32 ReceivedMessageArgument::AsInt32() const
|
||||
{
|
||||
if( !typeTag_ )
|
||||
if( !typeTagPtr_ )
|
||||
throw MissingArgumentException();
|
||||
else if( *typeTag_ == INT32_TYPE_TAG )
|
||||
else if( *typeTagPtr_ == INT32_TYPE_TAG )
|
||||
return AsInt32Unchecked();
|
||||
else
|
||||
throw WrongArgumentTypeException();
|
||||
@@ -239,10 +242,10 @@ int32 ReceivedMessageArgument::AsInt32Unchecked() const
|
||||
char c[4];
|
||||
} u;
|
||||
|
||||
u.c[0] = argument_[3];
|
||||
u.c[1] = argument_[2];
|
||||
u.c[2] = argument_[1];
|
||||
u.c[3] = argument_[0];
|
||||
u.c[0] = argumentPtr_[3];
|
||||
u.c[1] = argumentPtr_[2];
|
||||
u.c[2] = argumentPtr_[1];
|
||||
u.c[3] = argumentPtr_[0];
|
||||
|
||||
return u.i;
|
||||
#else
|
||||
@@ -253,9 +256,9 @@ int32 ReceivedMessageArgument::AsInt32Unchecked() const
|
||||
|
||||
float ReceivedMessageArgument::AsFloat() const
|
||||
{
|
||||
if( !typeTag_ )
|
||||
if( !typeTagPtr_ )
|
||||
throw MissingArgumentException();
|
||||
else if( *typeTag_ == FLOAT_TYPE_TAG )
|
||||
else if( *typeTagPtr_ == FLOAT_TYPE_TAG )
|
||||
return AsFloatUnchecked();
|
||||
else
|
||||
throw WrongArgumentTypeException();
|
||||
@@ -270,10 +273,10 @@ float ReceivedMessageArgument::AsFloatUnchecked() const
|
||||
char c[4];
|
||||
} u;
|
||||
|
||||
u.c[0] = argument_[3];
|
||||
u.c[1] = argument_[2];
|
||||
u.c[2] = argument_[1];
|
||||
u.c[3] = argument_[0];
|
||||
u.c[0] = argumentPtr_[3];
|
||||
u.c[1] = argumentPtr_[2];
|
||||
u.c[2] = argumentPtr_[1];
|
||||
u.c[3] = argumentPtr_[0];
|
||||
|
||||
return u.f;
|
||||
#else
|
||||
@@ -284,9 +287,9 @@ float ReceivedMessageArgument::AsFloatUnchecked() const
|
||||
|
||||
char ReceivedMessageArgument::AsChar() const
|
||||
{
|
||||
if( !typeTag_ )
|
||||
if( !typeTagPtr_ )
|
||||
throw MissingArgumentException();
|
||||
else if( *typeTag_ == CHAR_TYPE_TAG )
|
||||
else if( *typeTagPtr_ == CHAR_TYPE_TAG )
|
||||
return AsCharUnchecked();
|
||||
else
|
||||
throw WrongArgumentTypeException();
|
||||
@@ -295,15 +298,15 @@ char ReceivedMessageArgument::AsChar() const
|
||||
|
||||
char ReceivedMessageArgument::AsCharUnchecked() const
|
||||
{
|
||||
return (char)ToInt32( argument_ );
|
||||
return (char)ToInt32( argumentPtr_ );
|
||||
}
|
||||
|
||||
|
||||
uint32 ReceivedMessageArgument::AsRgbaColor() const
|
||||
{
|
||||
if( !typeTag_ )
|
||||
if( !typeTagPtr_ )
|
||||
throw MissingArgumentException();
|
||||
else if( *typeTag_ == RGBA_COLOR_TYPE_TAG )
|
||||
else if( *typeTagPtr_ == RGBA_COLOR_TYPE_TAG )
|
||||
return AsRgbaColorUnchecked();
|
||||
else
|
||||
throw WrongArgumentTypeException();
|
||||
@@ -312,15 +315,15 @@ uint32 ReceivedMessageArgument::AsRgbaColor() const
|
||||
|
||||
uint32 ReceivedMessageArgument::AsRgbaColorUnchecked() const
|
||||
{
|
||||
return ToUInt32( argument_ );
|
||||
return ToUInt32( argumentPtr_ );
|
||||
}
|
||||
|
||||
|
||||
uint32 ReceivedMessageArgument::AsMidiMessage() const
|
||||
{
|
||||
if( !typeTag_ )
|
||||
if( !typeTagPtr_ )
|
||||
throw MissingArgumentException();
|
||||
else if( *typeTag_ == MIDI_MESSAGE_TYPE_TAG )
|
||||
else if( *typeTagPtr_ == MIDI_MESSAGE_TYPE_TAG )
|
||||
return AsMidiMessageUnchecked();
|
||||
else
|
||||
throw WrongArgumentTypeException();
|
||||
@@ -329,15 +332,15 @@ uint32 ReceivedMessageArgument::AsMidiMessage() const
|
||||
|
||||
uint32 ReceivedMessageArgument::AsMidiMessageUnchecked() const
|
||||
{
|
||||
return ToUInt32( argument_ );
|
||||
return ToUInt32( argumentPtr_ );
|
||||
}
|
||||
|
||||
|
||||
int64 ReceivedMessageArgument::AsInt64() const
|
||||
{
|
||||
if( !typeTag_ )
|
||||
if( !typeTagPtr_ )
|
||||
throw MissingArgumentException();
|
||||
else if( *typeTag_ == INT64_TYPE_TAG )
|
||||
else if( *typeTagPtr_ == INT64_TYPE_TAG )
|
||||
return AsInt64Unchecked();
|
||||
else
|
||||
throw WrongArgumentTypeException();
|
||||
@@ -346,15 +349,15 @@ int64 ReceivedMessageArgument::AsInt64() const
|
||||
|
||||
int64 ReceivedMessageArgument::AsInt64Unchecked() const
|
||||
{
|
||||
return ToInt64( argument_ );
|
||||
return ToInt64( argumentPtr_ );
|
||||
}
|
||||
|
||||
|
||||
uint64 ReceivedMessageArgument::AsTimeTag() const
|
||||
{
|
||||
if( !typeTag_ )
|
||||
if( !typeTagPtr_ )
|
||||
throw MissingArgumentException();
|
||||
else if( *typeTag_ == TIME_TAG_TYPE_TAG )
|
||||
else if( *typeTagPtr_ == TIME_TAG_TYPE_TAG )
|
||||
return AsTimeTagUnchecked();
|
||||
else
|
||||
throw WrongArgumentTypeException();
|
||||
@@ -363,15 +366,15 @@ uint64 ReceivedMessageArgument::AsTimeTag() const
|
||||
|
||||
uint64 ReceivedMessageArgument::AsTimeTagUnchecked() const
|
||||
{
|
||||
return ToUInt64( argument_ );
|
||||
return ToUInt64( argumentPtr_ );
|
||||
}
|
||||
|
||||
|
||||
double ReceivedMessageArgument::AsDouble() const
|
||||
{
|
||||
if( !typeTag_ )
|
||||
if( !typeTagPtr_ )
|
||||
throw MissingArgumentException();
|
||||
else if( *typeTag_ == DOUBLE_TYPE_TAG )
|
||||
else if( *typeTagPtr_ == DOUBLE_TYPE_TAG )
|
||||
return AsDoubleUnchecked();
|
||||
else
|
||||
throw WrongArgumentTypeException();
|
||||
@@ -386,14 +389,14 @@ double ReceivedMessageArgument::AsDoubleUnchecked() const
|
||||
char c[8];
|
||||
} u;
|
||||
|
||||
u.c[0] = argument_[7];
|
||||
u.c[1] = argument_[6];
|
||||
u.c[2] = argument_[5];
|
||||
u.c[3] = argument_[4];
|
||||
u.c[4] = argument_[3];
|
||||
u.c[5] = argument_[2];
|
||||
u.c[6] = argument_[1];
|
||||
u.c[7] = argument_[0];
|
||||
u.c[0] = argumentPtr_[7];
|
||||
u.c[1] = argumentPtr_[6];
|
||||
u.c[2] = argumentPtr_[5];
|
||||
u.c[3] = argumentPtr_[4];
|
||||
u.c[4] = argumentPtr_[3];
|
||||
u.c[5] = argumentPtr_[2];
|
||||
u.c[6] = argumentPtr_[1];
|
||||
u.c[7] = argumentPtr_[0];
|
||||
|
||||
return u.d;
|
||||
#else
|
||||
@@ -404,10 +407,10 @@ double ReceivedMessageArgument::AsDoubleUnchecked() const
|
||||
|
||||
const char* ReceivedMessageArgument::AsString() const
|
||||
{
|
||||
if( !typeTag_ )
|
||||
if( !typeTagPtr_ )
|
||||
throw MissingArgumentException();
|
||||
else if( *typeTag_ == STRING_TYPE_TAG )
|
||||
return argument_;
|
||||
else if( *typeTagPtr_ == STRING_TYPE_TAG )
|
||||
return argumentPtr_;
|
||||
else
|
||||
throw WrongArgumentTypeException();
|
||||
}
|
||||
@@ -415,43 +418,81 @@ const char* ReceivedMessageArgument::AsString() const
|
||||
|
||||
const char* ReceivedMessageArgument::AsSymbol() const
|
||||
{
|
||||
if( !typeTag_ )
|
||||
if( !typeTagPtr_ )
|
||||
throw MissingArgumentException();
|
||||
else if( *typeTag_ == SYMBOL_TYPE_TAG )
|
||||
return argument_;
|
||||
else if( *typeTagPtr_ == SYMBOL_TYPE_TAG )
|
||||
return argumentPtr_;
|
||||
else
|
||||
throw WrongArgumentTypeException();
|
||||
}
|
||||
|
||||
|
||||
void ReceivedMessageArgument::AsBlob( const void*& data, unsigned long& size ) const
|
||||
void ReceivedMessageArgument::AsBlob( const void*& data, osc_bundle_element_size_t& size ) const
|
||||
{
|
||||
if( !typeTag_ )
|
||||
if( !typeTagPtr_ )
|
||||
throw MissingArgumentException();
|
||||
else if( *typeTag_ == BLOB_TYPE_TAG )
|
||||
else if( *typeTagPtr_ == BLOB_TYPE_TAG )
|
||||
AsBlobUnchecked( data, size );
|
||||
else
|
||||
throw WrongArgumentTypeException();
|
||||
}
|
||||
|
||||
|
||||
void ReceivedMessageArgument::AsBlobUnchecked( const void*& data, unsigned long& size ) const
|
||||
void ReceivedMessageArgument::AsBlobUnchecked( const void*& data, osc_bundle_element_size_t& size ) const
|
||||
{
|
||||
size = ToUInt32( argument_ );
|
||||
data = (void*)(argument_+4);
|
||||
// read blob size as an unsigned int then validate
|
||||
osc_bundle_element_size_t sizeResult = (osc_bundle_element_size_t)ToUInt32( argumentPtr_ );
|
||||
if( !IsValidElementSizeValue(sizeResult) )
|
||||
throw MalformedMessageException("invalid blob size");
|
||||
|
||||
size = sizeResult;
|
||||
data = (void*)(argumentPtr_+ osc::OSC_SIZEOF_INT32);
|
||||
}
|
||||
|
||||
std::size_t ReceivedMessageArgument::ComputeArrayItemCount() const
|
||||
{
|
||||
// it is only valid to call ComputeArrayItemCount when the argument is the array start marker
|
||||
if( !IsArrayBegin() )
|
||||
throw WrongArgumentTypeException();
|
||||
|
||||
std::size_t result = 0;
|
||||
unsigned int level = 0;
|
||||
const char *typeTag = typeTagPtr_ + 1;
|
||||
|
||||
// iterate through all type tags. note that ReceivedMessage::Init
|
||||
// has already checked that the message is well formed.
|
||||
while( *typeTag ) {
|
||||
switch( *typeTag++ ) {
|
||||
case ARRAY_BEGIN_TYPE_TAG:
|
||||
level += 1;
|
||||
break;
|
||||
|
||||
case ARRAY_END_TYPE_TAG:
|
||||
if(level == 0)
|
||||
return result;
|
||||
level -= 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if( level == 0 ) // only count items at level 0
|
||||
++result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void ReceivedMessageArgumentIterator::Advance()
|
||||
{
|
||||
if( !value_.typeTag_ )
|
||||
if( !value_.typeTagPtr_ )
|
||||
return;
|
||||
|
||||
switch( *value_.typeTag_++ ){
|
||||
switch( *value_.typeTagPtr_++ ){
|
||||
case '\0':
|
||||
// don't advance past end
|
||||
--value_.typeTag_;
|
||||
--value_.typeTagPtr_;
|
||||
break;
|
||||
|
||||
case TRUE_TYPE_TAG:
|
||||
@@ -468,14 +509,14 @@ void ReceivedMessageArgumentIterator::Advance()
|
||||
case RGBA_COLOR_TYPE_TAG:
|
||||
case MIDI_MESSAGE_TYPE_TAG:
|
||||
|
||||
value_.argument_ += 4;
|
||||
value_.argumentPtr_ += 4;
|
||||
break;
|
||||
|
||||
case INT64_TYPE_TAG:
|
||||
case TIME_TAG_TYPE_TAG:
|
||||
case DOUBLE_TYPE_TAG:
|
||||
|
||||
value_.argument_ += 8;
|
||||
value_.argumentPtr_ += 8;
|
||||
break;
|
||||
|
||||
case STRING_TYPE_TAG:
|
||||
@@ -485,26 +526,31 @@ void ReceivedMessageArgumentIterator::Advance()
|
||||
// the arguments have already been validated in
|
||||
// ReceivedMessage::Init() below.
|
||||
|
||||
value_.argument_ = FindStr4End( value_.argument_ );
|
||||
value_.argumentPtr_ = FindStr4End( value_.argumentPtr_ );
|
||||
break;
|
||||
|
||||
case BLOB_TYPE_TAG:
|
||||
{
|
||||
uint32 blobSize = ToUInt32( value_.argument_ );
|
||||
value_.argument_ = value_.argument_ + 4 + RoundUp4( blobSize );
|
||||
// treat blob size as an unsigned int for the purposes of this calculation
|
||||
uint32 blobSize = ToUInt32( value_.argumentPtr_ );
|
||||
value_.argumentPtr_ = value_.argumentPtr_ + osc::OSC_SIZEOF_INT32 + RoundUp4( blobSize );
|
||||
}
|
||||
break;
|
||||
|
||||
case ARRAY_BEGIN_TYPE_TAG:
|
||||
case ARRAY_END_TYPE_TAG:
|
||||
|
||||
// [ Indicates the beginning of an array. The tags following are for
|
||||
// data in the Array until a close brace tag is reached.
|
||||
// ] Indicates the end of an array.
|
||||
|
||||
// zero length, don't advance argument ptr
|
||||
break;
|
||||
|
||||
default: // unknown type tag
|
||||
// don't advance
|
||||
--value_.typeTag_;
|
||||
--value_.typeTagPtr_;
|
||||
break;
|
||||
|
||||
|
||||
// not handled:
|
||||
// [ Indicates the beginning of an array. The tags following are for
|
||||
// data in the Array until a close brace tag is reached.
|
||||
// ] Indicates the end of an array.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,12 +582,15 @@ uint32 ReceivedMessage::AddressPatternAsUInt32() const
|
||||
}
|
||||
|
||||
|
||||
void ReceivedMessage::Init( const char *message, unsigned long size )
|
||||
void ReceivedMessage::Init( const char *message, osc_bundle_element_size_t size )
|
||||
{
|
||||
if( !IsValidElementSizeValue(size) )
|
||||
throw MalformedMessageException( "invalid message size" );
|
||||
|
||||
if( size == 0 )
|
||||
throw MalformedMessageException( "zero length messages not permitted" );
|
||||
|
||||
if( (size & 0x03L) != 0 )
|
||||
if( !IsMultipleOf4(size) )
|
||||
throw MalformedMessageException( "message size must be multiple of four" );
|
||||
|
||||
const char *end = message + size;
|
||||
@@ -580,6 +629,7 @@ void ReceivedMessage::Init( const char *message, unsigned long size )
|
||||
|
||||
const char *typeTag = typeTagsBegin_;
|
||||
const char *argument = arguments_;
|
||||
unsigned int arrayLevel = 0;
|
||||
|
||||
do{
|
||||
switch( *typeTag ){
|
||||
@@ -587,10 +637,22 @@ void ReceivedMessage::Init( const char *message, unsigned long size )
|
||||
case FALSE_TYPE_TAG:
|
||||
case NIL_TYPE_TAG:
|
||||
case INFINITUM_TYPE_TAG:
|
||||
|
||||
// zero length
|
||||
break;
|
||||
|
||||
// [ Indicates the beginning of an array. The tags following are for
|
||||
// data in the Array until a close brace tag is reached.
|
||||
// ] Indicates the end of an array.
|
||||
case ARRAY_BEGIN_TYPE_TAG:
|
||||
++arrayLevel;
|
||||
// (zero length argument data)
|
||||
break;
|
||||
|
||||
case ARRAY_END_TYPE_TAG:
|
||||
--arrayLevel;
|
||||
// (zero length argument data)
|
||||
break;
|
||||
|
||||
case INT32_TYPE_TAG:
|
||||
case FLOAT_TYPE_TAG:
|
||||
case CHAR_TYPE_TAG:
|
||||
@@ -627,11 +689,12 @@ void ReceivedMessage::Init( const char *message, unsigned long size )
|
||||
|
||||
case BLOB_TYPE_TAG:
|
||||
{
|
||||
if( argument + 4 > end )
|
||||
if( argument + osc::OSC_SIZEOF_INT32 > end )
|
||||
MalformedMessageException( "arguments exceed message size" );
|
||||
|
||||
// treat blob size as an unsigned int for the purposes of this calculation
|
||||
uint32 blobSize = ToUInt32( argument );
|
||||
argument = argument + 4 + RoundUp4( blobSize );
|
||||
argument = argument + osc::OSC_SIZEOF_INT32 + RoundUp4( blobSize );
|
||||
if( argument > end )
|
||||
MalformedMessageException( "arguments exceed message size" );
|
||||
}
|
||||
@@ -639,16 +702,22 @@ void ReceivedMessage::Init( const char *message, unsigned long size )
|
||||
|
||||
default:
|
||||
throw MalformedMessageException( "unknown type tag" );
|
||||
|
||||
// not handled:
|
||||
// [ Indicates the beginning of an array. The tags following are for
|
||||
// data in the Array until a close brace tag is reached.
|
||||
// ] Indicates the end of an array.
|
||||
}
|
||||
|
||||
}while( *++typeTag != '\0' );
|
||||
typeTagsEnd_ = typeTag;
|
||||
|
||||
if( arrayLevel != 0 )
|
||||
throw MalformedMessageException( "array was not terminated before end of message (expected ']' end of array tag)" );
|
||||
}
|
||||
|
||||
// These invariants should be guaranteed by the above code.
|
||||
// we depend on them in the implementation of ArgumentCount()
|
||||
#ifndef NDEBUG
|
||||
std::ptrdiff_t argumentCount = typeTagsEnd_ - typeTagsBegin_;
|
||||
assert( argumentCount >= 0 );
|
||||
assert( argumentCount <= OSC_INT32_MAX );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -668,12 +737,16 @@ ReceivedBundle::ReceivedBundle( const ReceivedBundleElement& bundleElement )
|
||||
}
|
||||
|
||||
|
||||
void ReceivedBundle::Init( const char *bundle, unsigned long size )
|
||||
void ReceivedBundle::Init( const char *bundle, osc_bundle_element_size_t size )
|
||||
{
|
||||
|
||||
if( !IsValidElementSizeValue(size) )
|
||||
throw MalformedBundleException( "invalid bundle size" );
|
||||
|
||||
if( size < 16 )
|
||||
throw MalformedBundleException( "packet too short for bundle" );
|
||||
|
||||
if( (size & 0x03L) != 0 )
|
||||
if( !IsMultipleOf4(size) )
|
||||
throw MalformedBundleException( "bundle size must be multiple of four" );
|
||||
|
||||
if( bundle[0] != '#'
|
||||
@@ -693,14 +766,15 @@ void ReceivedBundle::Init( const char *bundle, unsigned long size )
|
||||
const char *p = timeTag_ + 8;
|
||||
|
||||
while( p < end_ ){
|
||||
if( p + 4 > end_ )
|
||||
if( p + osc::OSC_SIZEOF_INT32 > end_ )
|
||||
throw MalformedBundleException( "packet too short for elementSize" );
|
||||
|
||||
// treat element size as an unsigned int for the purposes of this calculation
|
||||
uint32 elementSize = ToUInt32( p );
|
||||
if( (elementSize & 0x03L) != 0 )
|
||||
if( (elementSize & ((uint32)0x03)) != 0 )
|
||||
throw MalformedBundleException( "bundle element size must be multiple of four" );
|
||||
|
||||
p += 4 + elementSize;
|
||||
p += osc::OSC_SIZEOF_INT32 + elementSize;
|
||||
if( p > end_ )
|
||||
throw MalformedBundleException( "packet too short for bundle element" );
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,8 +23,23 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCRECEIVEDELEMENTS_H
|
||||
#define INCLUDED_OSCRECEIVEDELEMENTS_H
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCPACK_OSCRECEIVEDELEMENTS_H
|
||||
#define INCLUDED_OSCPACK_OSCRECEIVEDELEMENTS_H
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstring> // size_t
|
||||
|
||||
#include "OscTypes.h"
|
||||
#include "OscException.h"
|
||||
@@ -37,6 +48,12 @@
|
||||
namespace osc{
|
||||
|
||||
|
||||
class MalformedPacketException : public Exception{
|
||||
public:
|
||||
MalformedPacketException( const char *w="malformed packet" )
|
||||
: Exception( w ) {}
|
||||
};
|
||||
|
||||
class MalformedMessageException : public Exception{
|
||||
public:
|
||||
MalformedMessageException( const char *w="malformed message" )
|
||||
@@ -70,37 +87,73 @@ public:
|
||||
|
||||
class ReceivedPacket{
|
||||
public:
|
||||
ReceivedPacket( const char *contents, int32 size )
|
||||
// Although the OSC spec is not entirely clear on this, we only support
|
||||
// packets up to 0x7FFFFFFC bytes long (the maximum 4-byte aligned value
|
||||
// representable by an int32). An exception will be raised if you pass a
|
||||
// larger value to the ReceivedPacket() constructor.
|
||||
|
||||
ReceivedPacket( const char *contents, osc_bundle_element_size_t size )
|
||||
: contents_( contents )
|
||||
, size_( size ) {}
|
||||
, size_( ValidateSize(size) ) {}
|
||||
|
||||
ReceivedPacket( const char *contents, std::size_t size )
|
||||
: contents_( contents )
|
||||
, size_( ValidateSize( (osc_bundle_element_size_t)size ) ) {}
|
||||
|
||||
#if !(defined(__x86_64__) || defined(_M_X64))
|
||||
ReceivedPacket( const char *contents, int size )
|
||||
: contents_( contents )
|
||||
, size_( ValidateSize( (osc_bundle_element_size_t)size ) ) {}
|
||||
#endif
|
||||
|
||||
bool IsMessage() const { return !IsBundle(); }
|
||||
bool IsBundle() const;
|
||||
|
||||
int32 Size() const { return size_; }
|
||||
osc_bundle_element_size_t Size() const { return size_; }
|
||||
const char *Contents() const { return contents_; }
|
||||
|
||||
private:
|
||||
const char *contents_;
|
||||
int32 size_;
|
||||
osc_bundle_element_size_t size_;
|
||||
|
||||
static osc_bundle_element_size_t ValidateSize( osc_bundle_element_size_t size )
|
||||
{
|
||||
// sanity check integer types declared in OscTypes.h
|
||||
// you'll need to fix OscTypes.h if any of these asserts fail
|
||||
assert( sizeof(osc::int32) == 4 );
|
||||
assert( sizeof(osc::uint32) == 4 );
|
||||
assert( sizeof(osc::int64) == 8 );
|
||||
assert( sizeof(osc::uint64) == 8 );
|
||||
|
||||
if( !IsValidElementSizeValue(size) )
|
||||
throw MalformedPacketException( "invalid packet size" );
|
||||
|
||||
if( size == 0 )
|
||||
throw MalformedPacketException( "zero length elements not permitted" );
|
||||
|
||||
if( !IsMultipleOf4(size) )
|
||||
throw MalformedPacketException( "element size must be multiple of four" );
|
||||
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ReceivedBundleElement{
|
||||
public:
|
||||
ReceivedBundleElement( const char *size )
|
||||
: size_( size ) {}
|
||||
ReceivedBundleElement( const char *sizePtr )
|
||||
: sizePtr_( sizePtr ) {}
|
||||
|
||||
friend class ReceivedBundleElementIterator;
|
||||
|
||||
bool IsMessage() const { return !IsBundle(); }
|
||||
bool IsBundle() const;
|
||||
|
||||
int32 Size() const;
|
||||
const char *Contents() const { return size_ + 4; }
|
||||
osc_bundle_element_size_t Size() const;
|
||||
const char *Contents() const { return sizePtr_ + osc::OSC_SIZEOF_INT32; }
|
||||
|
||||
private:
|
||||
const char *size_;
|
||||
const char *sizePtr_;
|
||||
};
|
||||
|
||||
|
||||
@@ -132,11 +185,11 @@ public:
|
||||
private:
|
||||
ReceivedBundleElement value_;
|
||||
|
||||
void Advance() { value_.size_ = value_.Contents() + value_.Size(); }
|
||||
void Advance() { value_.sizePtr_ = value_.Contents() + value_.Size(); }
|
||||
|
||||
bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const
|
||||
{
|
||||
return value_.size_ == rhs.value_.size_;
|
||||
return value_.sizePtr_ == rhs.value_.sizePtr_;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -155,73 +208,79 @@ inline bool operator!=(const ReceivedBundleElementIterator& lhs,
|
||||
|
||||
class ReceivedMessageArgument{
|
||||
public:
|
||||
ReceivedMessageArgument( const char *typeTag, const char *argument )
|
||||
: typeTag_( typeTag )
|
||||
, argument_( argument ) {}
|
||||
ReceivedMessageArgument( const char *typeTagPtr, const char *argumentPtr )
|
||||
: typeTagPtr_( typeTagPtr )
|
||||
, argumentPtr_( argumentPtr ) {}
|
||||
|
||||
friend class ReceivedMessageArgumentIterator;
|
||||
|
||||
const char TypeTag() const { return *typeTag_; }
|
||||
char TypeTag() const { return *typeTagPtr_; }
|
||||
|
||||
// the unchecked methods below don't check whether the argument actually
|
||||
// is of the specified type. they should only be used if you've already
|
||||
// checked the type tag or the associated IsType() method.
|
||||
|
||||
bool IsBool() const
|
||||
{ return *typeTag_ == TRUE_TYPE_TAG || *typeTag_ == FALSE_TYPE_TAG; }
|
||||
{ return *typeTagPtr_ == TRUE_TYPE_TAG || *typeTagPtr_ == FALSE_TYPE_TAG; }
|
||||
bool AsBool() const;
|
||||
bool AsBoolUnchecked() const;
|
||||
|
||||
bool IsNil() const { return *typeTag_ == NIL_TYPE_TAG; }
|
||||
bool IsInfinitum() const { return *typeTag_ == INFINITUM_TYPE_TAG; }
|
||||
bool IsNil() const { return *typeTagPtr_ == NIL_TYPE_TAG; }
|
||||
bool IsInfinitum() const { return *typeTagPtr_ == INFINITUM_TYPE_TAG; }
|
||||
|
||||
bool IsInt32() const { return *typeTag_ == INT32_TYPE_TAG; }
|
||||
bool IsInt32() const { return *typeTagPtr_ == INT32_TYPE_TAG; }
|
||||
int32 AsInt32() const;
|
||||
int32 AsInt32Unchecked() const;
|
||||
|
||||
bool IsFloat() const { return *typeTag_ == FLOAT_TYPE_TAG; }
|
||||
bool IsFloat() const { return *typeTagPtr_ == FLOAT_TYPE_TAG; }
|
||||
float AsFloat() const;
|
||||
float AsFloatUnchecked() const;
|
||||
|
||||
bool IsChar() const { return *typeTag_ == CHAR_TYPE_TAG; }
|
||||
bool IsChar() const { return *typeTagPtr_ == CHAR_TYPE_TAG; }
|
||||
char AsChar() const;
|
||||
char AsCharUnchecked() const;
|
||||
|
||||
bool IsRgbaColor() const { return *typeTag_ == RGBA_COLOR_TYPE_TAG; }
|
||||
bool IsRgbaColor() const { return *typeTagPtr_ == RGBA_COLOR_TYPE_TAG; }
|
||||
uint32 AsRgbaColor() const;
|
||||
uint32 AsRgbaColorUnchecked() const;
|
||||
|
||||
bool IsMidiMessage() const { return *typeTag_ == MIDI_MESSAGE_TYPE_TAG; }
|
||||
bool IsMidiMessage() const { return *typeTagPtr_ == MIDI_MESSAGE_TYPE_TAG; }
|
||||
uint32 AsMidiMessage() const;
|
||||
uint32 AsMidiMessageUnchecked() const;
|
||||
|
||||
bool IsInt64() const { return *typeTag_ == INT64_TYPE_TAG; }
|
||||
bool IsInt64() const { return *typeTagPtr_ == INT64_TYPE_TAG; }
|
||||
int64 AsInt64() const;
|
||||
int64 AsInt64Unchecked() const;
|
||||
|
||||
bool IsTimeTag() const { return *typeTag_ == TIME_TAG_TYPE_TAG; }
|
||||
bool IsTimeTag() const { return *typeTagPtr_ == TIME_TAG_TYPE_TAG; }
|
||||
uint64 AsTimeTag() const;
|
||||
uint64 AsTimeTagUnchecked() const;
|
||||
|
||||
bool IsDouble() const { return *typeTag_ == DOUBLE_TYPE_TAG; }
|
||||
bool IsDouble() const { return *typeTagPtr_ == DOUBLE_TYPE_TAG; }
|
||||
double AsDouble() const;
|
||||
double AsDoubleUnchecked() const;
|
||||
|
||||
bool IsString() const { return *typeTag_ == STRING_TYPE_TAG; }
|
||||
bool IsString() const { return *typeTagPtr_ == STRING_TYPE_TAG; }
|
||||
const char* AsString() const;
|
||||
const char* AsStringUnchecked() const { return argument_; }
|
||||
const char* AsStringUnchecked() const { return argumentPtr_; }
|
||||
|
||||
bool IsSymbol() const { return *typeTag_ == SYMBOL_TYPE_TAG; }
|
||||
bool IsSymbol() const { return *typeTagPtr_ == SYMBOL_TYPE_TAG; }
|
||||
const char* AsSymbol() const;
|
||||
const char* AsSymbolUnchecked() const { return argument_; }
|
||||
const char* AsSymbolUnchecked() const { return argumentPtr_; }
|
||||
|
||||
bool IsBlob() const { return *typeTag_ == BLOB_TYPE_TAG; }
|
||||
void AsBlob( const void*& data, unsigned long& size ) const;
|
||||
void AsBlobUnchecked( const void*& data, unsigned long& size ) const;
|
||||
bool IsBlob() const { return *typeTagPtr_ == BLOB_TYPE_TAG; }
|
||||
void AsBlob( const void*& data, osc_bundle_element_size_t& size ) const;
|
||||
void AsBlobUnchecked( const void*& data, osc_bundle_element_size_t& size ) const;
|
||||
|
||||
bool IsArrayBegin() const { return *typeTagPtr_ == ARRAY_BEGIN_TYPE_TAG; }
|
||||
bool IsArrayEnd() const { return *typeTagPtr_ == ARRAY_END_TYPE_TAG; }
|
||||
// Calculate the number of top-level items in the array. Nested arrays count as one item.
|
||||
// Only valid at array start. Will throw an exception if IsArrayStart() == false.
|
||||
std::size_t ComputeArrayItemCount() const;
|
||||
|
||||
private:
|
||||
const char *typeTag_;
|
||||
const char *argument_;
|
||||
const char *typeTagPtr_;
|
||||
const char *argumentPtr_;
|
||||
};
|
||||
|
||||
|
||||
@@ -257,7 +316,7 @@ private:
|
||||
|
||||
bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const
|
||||
{
|
||||
return value_.typeTag_ == rhs.value_.typeTag_;
|
||||
return value_.typeTagPtr_ == rhs.value_.typeTagPtr_;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -299,6 +358,7 @@ public:
|
||||
|
||||
// not sure if it would be useful to stream Nil and Infinitum
|
||||
// for now it's not possible
|
||||
// same goes for array boundaries
|
||||
|
||||
ReceivedMessageArgumentStream& operator>>( int32& rhs )
|
||||
{
|
||||
@@ -401,6 +461,8 @@ public:
|
||||
|
||||
ReceivedMessageArgumentStream& operator>>( MessageTerminator& rhs )
|
||||
{
|
||||
(void) rhs; // suppress unused parameter warning
|
||||
|
||||
if( !Eos() )
|
||||
throw ExcessArgumentException();
|
||||
|
||||
@@ -410,18 +472,18 @@ public:
|
||||
|
||||
|
||||
class ReceivedMessage{
|
||||
void Init( const char *bundle, unsigned long size );
|
||||
void Init( const char *bundle, osc_bundle_element_size_t size );
|
||||
public:
|
||||
explicit ReceivedMessage( const ReceivedPacket& packet );
|
||||
explicit ReceivedMessage( const ReceivedBundleElement& bundleElement );
|
||||
|
||||
const char *AddressPattern() const { return addressPattern_; }
|
||||
|
||||
// Support for non-standad SuperCollider integer address patterns:
|
||||
// Support for non-standard SuperCollider integer address patterns:
|
||||
bool AddressPatternIsUInt32() const;
|
||||
uint32 AddressPatternAsUInt32() const;
|
||||
|
||||
unsigned long ArgumentCount() const { return static_cast<unsigned long>(typeTagsEnd_ - typeTagsBegin_); }
|
||||
uint32 ArgumentCount() const { return static_cast<uint32>(typeTagsEnd_ - typeTagsBegin_); }
|
||||
|
||||
const char *TypeTags() const { return typeTagsBegin_; }
|
||||
|
||||
@@ -452,14 +514,14 @@ private:
|
||||
|
||||
|
||||
class ReceivedBundle{
|
||||
void Init( const char *message, unsigned long size );
|
||||
void Init( const char *message, osc_bundle_element_size_t size );
|
||||
public:
|
||||
explicit ReceivedBundle( const ReceivedPacket& packet );
|
||||
explicit ReceivedBundle( const ReceivedBundleElement& bundleElement );
|
||||
|
||||
uint64 TimeTag() const;
|
||||
|
||||
unsigned long ElementCount() const { return elementCount_; }
|
||||
uint32 ElementCount() const { return elementCount_; }
|
||||
|
||||
typedef ReceivedBundleElementIterator const_iterator;
|
||||
|
||||
@@ -476,11 +538,11 @@ public:
|
||||
private:
|
||||
const char *timeTag_;
|
||||
const char *end_;
|
||||
unsigned long elementCount_;
|
||||
uint32 elementCount_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace osc
|
||||
|
||||
|
||||
#endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */
|
||||
#endif /* INCLUDED_OSCPACK_OSCRECEIVEDELEMENTS_H */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,6 +23,17 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#include "OscTypes.h"
|
||||
|
||||
namespace osc{
|
||||
@@ -34,7 +41,12 @@ namespace osc{
|
||||
BundleInitiator BeginBundleImmediate(1);
|
||||
BundleTerminator EndBundle;
|
||||
MessageTerminator EndMessage;
|
||||
NilType Nil;
|
||||
NilType OscNil;
|
||||
#ifndef _OBJC_OBJC_H_
|
||||
NilType Nil; // Objective-C defines Nil. so our Nil is deprecated. use OscNil instead
|
||||
#endif
|
||||
InfinitumType Infinitum;
|
||||
ArrayInitiator BeginArray;
|
||||
ArrayTerminator EndArray;
|
||||
|
||||
} // namespace osc
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,8 +23,19 @@
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCTYPES_H
|
||||
#define INCLUDED_OSCTYPES_H
|
||||
|
||||
/*
|
||||
The text above constitutes the entire oscpack license; however,
|
||||
the oscpack developer(s) also make the following non-binding requests:
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. It is also
|
||||
requested that these non-binding requests be included whenever the
|
||||
above license is reproduced.
|
||||
*/
|
||||
#ifndef INCLUDED_OSCPACK_OSCTYPES_H
|
||||
#define INCLUDED_OSCPACK_OSCTYPES_H
|
||||
|
||||
|
||||
namespace osc{
|
||||
@@ -40,6 +47,11 @@ namespace osc{
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
|
||||
#elif defined(__x86_64__) || defined(_M_X64)
|
||||
|
||||
typedef long int64;
|
||||
typedef unsigned long uint64;
|
||||
|
||||
#else
|
||||
|
||||
typedef long long int64;
|
||||
@@ -49,7 +61,7 @@ typedef unsigned long long uint64;
|
||||
|
||||
|
||||
|
||||
#ifdef x86_64
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
|
||||
typedef signed int int32;
|
||||
typedef unsigned int uint32;
|
||||
@@ -62,6 +74,41 @@ typedef unsigned long uint32;
|
||||
#endif
|
||||
|
||||
|
||||
enum ValueTypeSizes{
|
||||
OSC_SIZEOF_INT32 = 4,
|
||||
OSC_SIZEOF_UINT32 = 4,
|
||||
OSC_SIZEOF_INT64 = 8,
|
||||
OSC_SIZEOF_UINT64 = 8,
|
||||
};
|
||||
|
||||
|
||||
// osc_bundle_element_size_t is used for the size of bundle elements and blobs
|
||||
// the OSC spec specifies these as int32 (signed) but we ensure that they
|
||||
// are always positive since negative field sizes make no sense.
|
||||
|
||||
typedef int32 osc_bundle_element_size_t;
|
||||
|
||||
enum {
|
||||
OSC_INT32_MAX = 0x7FFFFFFF,
|
||||
|
||||
// Element sizes are specified to be int32, and are always rounded up to nearest
|
||||
// multiple of 4. Therefore their values can't be greater than 0x7FFFFFFC.
|
||||
OSC_BUNDLE_ELEMENT_SIZE_MAX = 0x7FFFFFFC
|
||||
};
|
||||
|
||||
|
||||
inline bool IsValidElementSizeValue( osc_bundle_element_size_t x )
|
||||
{
|
||||
// sizes may not be negative or exceed OSC_BUNDLE_ELEMENT_SIZE_MAX
|
||||
return x >= 0 && x <= OSC_BUNDLE_ELEMENT_SIZE_MAX;
|
||||
}
|
||||
|
||||
|
||||
inline bool IsMultipleOf4( osc_bundle_element_size_t x )
|
||||
{
|
||||
return (x & ((osc_bundle_element_size_t)0x03)) == 0;
|
||||
}
|
||||
|
||||
|
||||
enum TypeTagValues {
|
||||
TRUE_TYPE_TAG = 'T',
|
||||
@@ -78,7 +125,9 @@ enum TypeTagValues {
|
||||
DOUBLE_TYPE_TAG = 'd',
|
||||
STRING_TYPE_TAG = 's',
|
||||
SYMBOL_TYPE_TAG = 'S',
|
||||
BLOB_TYPE_TAG = 'b'
|
||||
BLOB_TYPE_TAG = 'b',
|
||||
ARRAY_BEGIN_TYPE_TAG = '[',
|
||||
ARRAY_END_TYPE_TAG = ']'
|
||||
};
|
||||
|
||||
|
||||
@@ -120,8 +169,11 @@ extern MessageTerminator EndMessage;
|
||||
struct NilType{
|
||||
};
|
||||
|
||||
extern NilType Nil;
|
||||
extern NilType OscNil;
|
||||
|
||||
#ifndef _OBJC_OBJC_H_
|
||||
extern NilType Nil; // Objective-C defines Nil. so our Nil is deprecated. use OscNil instead
|
||||
#endif
|
||||
|
||||
struct InfinitumType{
|
||||
};
|
||||
@@ -166,13 +218,23 @@ struct Symbol{
|
||||
|
||||
struct Blob{
|
||||
Blob() {}
|
||||
explicit Blob( const void* data_, unsigned long size_ )
|
||||
explicit Blob( const void* data_, osc_bundle_element_size_t size_ )
|
||||
: data( data_ ), size( size_ ) {}
|
||||
const void* data;
|
||||
unsigned long size;
|
||||
osc_bundle_element_size_t size;
|
||||
};
|
||||
|
||||
struct ArrayInitiator{
|
||||
};
|
||||
|
||||
extern ArrayInitiator BeginArray;
|
||||
|
||||
struct ArrayTerminator{
|
||||
};
|
||||
|
||||
extern ArrayTerminator EndArray;
|
||||
|
||||
} // namespace osc
|
||||
|
||||
|
||||
#endif /* INCLUDED_OSCTYPES_H */
|
||||
#endif /* INCLUDED_OSCPACK_OSCTYPES_H */
|
||||
|
||||
Reference in New Issue
Block a user