Update to OSCPack v1.1

This commit is contained in:
brunoherbelin
2020-10-20 18:27:26 +02:00
parent 65aefc9fb8
commit bbeb99056a
23 changed files with 1217 additions and 729 deletions

View File

@@ -1,34 +1,34 @@
oscpack -- Open Sound Control (OSC) packet manipulation library
http://www.rossbencina.com/code/oscpack
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
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
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.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
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
oscpack -- Open Sound Control (OSC) packet manipulation library
http://www.rossbencina.com/code/oscpack
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
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
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.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
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.

View File

@@ -1,150 +1,150 @@
oscpack -- Open Sound Control packet manipulation library
A simple C++ library for packing and unpacking OSC packets.
http://www.rossbencina.com/code/oscpack
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
Oscpack is simply a set of C++ classes for packing and unpacking OSC packets.
Oscpack includes a minimal set of UDP networking classes for Windows and POSIX.
The networking classes are sufficient for writing many OSC applications and servers,
but you are encouraged to use another networking framework if it better suits your needs.
Oscpack is not an OSC application framework. It doesn't include infrastructure for
constructing or routing OSC namespaces, just classes for easily constructing,
sending, receiving and parsing OSC packets. The library should also be easy to use
for other transport methods (e.g. serial).
The key goals of the oscpack library are:
- Be a simple and complete implementation of OSC
- Be portable to a wide variety of platforms
- Allow easy development of robust OSC applications
(for example it should be impossible to crash a server
by sending it malformed packets, and difficult to create
malformed packets.)
Here's a quick run down of the key files:
osc/OscReceivedElements -- classes for parsing a packet
osc/OscPrintRecievedElements -- iostream << operators for printing packet elements
osc/OscOutboundPacketStream -- a class for packing messages into a packet
osc/OscPacketListener -- base class for listening to OSC packets on a UdpSocket
ip/IpEndpointName -- class that represents an IP address and port number
ip/UdpSocket -- classes for UDP transmission and listening sockets
tests/OscUnitTests -- unit test program for the OSC modules
tests/OscSendTests -- examples of how to send messages
tests/OscReceiveTest -- example of how to receive the messages sent by OSCSendTests
examples/OscDump -- a program that prints received OSC packets
examples/SimpleSend -- a minimal program to send an OSC message
examples/SimpleReceive -- a minimal program to receive an OSC message
osc/ contains all of the OSC related classes
ip/ contains the networking classes
ip/windows contains the Windows implementation of the networking classes
ip/posix contains the POSIX implementation of the networking classes
Building
--------
The idea is that you will embed this source code in your projects as you
see fit. The Makefile has an install rule for building a shared library and
installing headers in usr/local. It can also build a static library.
There is a CMakeLists.txt for building with cmake.
Makefile builds
...............
The Makefile works for Linux and Max OS X. It should also work on other platforms
that have make. Just run:
$ make
You can run "make install" if you like.
Cmake builds
............
There is a CMakeLists.txt file which has been tested with cmake on
Windows and Linux. It should work on other platforms too.
For example, to generate a Visual Studio 10 project, run cmake
like this:
> cmake -G "Visual Studio 10"
Run cmake without any parameters to get a list of available generators.
Mingw build batch file
......................
For Windows there is a batch file for doing a simple test build with
MinGW gcc called make.MinGW32.bat. This will build the test executables
and oscdump in ./bin and run the unit tests.
Note:
In some rare instances you may need to edit the Makefile or
osc/OscHostEndianness.h to configure oscpack for the endianness of your
processor (see the comments at the top of the Makefile for details).
Verification test
-----------------
To run the unit tests:
$ ./bin/OscUnitTests
To run the send and receive tests. Open two terminals. In one run:
$ ./bin/OscReceiveTest
Then in the other terminal run:
$./bin/OscSendTests
You should see an indication that the messages were received
in the first terminal.
Note that OscSendTests intentionally sends some unexpected
message parameters to test exception handling in the receiver.
You will see some "error while parsing message" messages printed.
You can use ./bin/OscDump to print out OSC messages received
from any program, including the test programs.
--
If you fix anything or write a set of TCP send/receive classes
please consider sending me a patch. My email address is
rossb@audiomulch.com. Thanks :)
For more information about Open Sound Control, see:
http://opensoundcontrol.org/
Thanks to Till Bovermann for helping with POSIX networking code and
Mac compatibility, and to Martin Kaltenbrunner and the rest of the
reacTable team for giving me a reason to finish this library. Thanks
to Merlijn Blaauw for reviewing the interfaces. Thanks to Xavier Oliver
for additional help with Linux builds and POSIX implementation details.
Portions developed at the Music Technology Group, Audiovisual Institute,
University Pompeu Fabra, Barcelona, during my stay as a visiting
researcher, November 2004 - September 2005.
Thanks to Syneme at the University of Calgary for providing financial
support for the 1.1.0 update, December 2012 - March 2013.
See the file CHANGES for information about recent updates.
See the file LICENSE for information about distributing and using this code.
###
oscpack -- Open Sound Control packet manipulation library
A simple C++ library for packing and unpacking OSC packets.
http://www.rossbencina.com/code/oscpack
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
Oscpack is simply a set of C++ classes for packing and unpacking OSC packets.
Oscpack includes a minimal set of UDP networking classes for Windows and POSIX.
The networking classes are sufficient for writing many OSC applications and servers,
but you are encouraged to use another networking framework if it better suits your needs.
Oscpack is not an OSC application framework. It doesn't include infrastructure for
constructing or routing OSC namespaces, just classes for easily constructing,
sending, receiving and parsing OSC packets. The library should also be easy to use
for other transport methods (e.g. serial).
The key goals of the oscpack library are:
- Be a simple and complete implementation of OSC
- Be portable to a wide variety of platforms
- Allow easy development of robust OSC applications
(for example it should be impossible to crash a server
by sending it malformed packets, and difficult to create
malformed packets.)
Here's a quick run down of the key files:
osc/OscReceivedElements -- classes for parsing a packet
osc/OscPrintRecievedElements -- iostream << operators for printing packet elements
osc/OscOutboundPacketStream -- a class for packing messages into a packet
osc/OscPacketListener -- base class for listening to OSC packets on a UdpSocket
ip/IpEndpointName -- class that represents an IP address and port number
ip/UdpSocket -- classes for UDP transmission and listening sockets
tests/OscUnitTests -- unit test program for the OSC modules
tests/OscSendTests -- examples of how to send messages
tests/OscReceiveTest -- example of how to receive the messages sent by OSCSendTests
examples/OscDump -- a program that prints received OSC packets
examples/SimpleSend -- a minimal program to send an OSC message
examples/SimpleReceive -- a minimal program to receive an OSC message
osc/ contains all of the OSC related classes
ip/ contains the networking classes
ip/windows contains the Windows implementation of the networking classes
ip/posix contains the POSIX implementation of the networking classes
Building
--------
The idea is that you will embed this source code in your projects as you
see fit. The Makefile has an install rule for building a shared library and
installing headers in usr/local. It can also build a static library.
There is a CMakeLists.txt for building with cmake.
Makefile builds
...............
The Makefile works for Linux and Max OS X. It should also work on other platforms
that have make. Just run:
$ make
You can run "make install" if you like.
Cmake builds
............
There is a CMakeLists.txt file which has been tested with cmake on
Windows and Linux. It should work on other platforms too.
For example, to generate a Visual Studio 10 project, run cmake
like this:
> cmake -G "Visual Studio 10"
Run cmake without any parameters to get a list of available generators.
Mingw build batch file
......................
For Windows there is a batch file for doing a simple test build with
MinGW gcc called make.MinGW32.bat. This will build the test executables
and oscdump in ./bin and run the unit tests.
Note:
In some rare instances you may need to edit the Makefile or
osc/OscHostEndianness.h to configure oscpack for the endianness of your
processor (see the comments at the top of the Makefile for details).
Verification test
-----------------
To run the unit tests:
$ ./bin/OscUnitTests
To run the send and receive tests. Open two terminals. In one run:
$ ./bin/OscReceiveTest
Then in the other terminal run:
$./bin/OscSendTests
You should see an indication that the messages were received
in the first terminal.
Note that OscSendTests intentionally sends some unexpected
message parameters to test exception handling in the receiver.
You will see some "error while parsing message" messages printed.
You can use ./bin/OscDump to print out OSC messages received
from any program, including the test programs.
--
If you fix anything or write a set of TCP send/receive classes
please consider sending me a patch. My email address is
rossb@audiomulch.com. Thanks :)
For more information about Open Sound Control, see:
http://opensoundcontrol.org/
Thanks to Till Bovermann for helping with POSIX networking code and
Mac compatibility, and to Martin Kaltenbrunner and the rest of the
reacTable team for giving me a reason to finish this library. Thanks
to Merlijn Blaauw for reviewing the interfaces. Thanks to Xavier Oliver
for additional help with Linux builds and POSIX implementation details.
Portions developed at the Music Technology Group, Audiovisual Institute,
University Pompeu Fabra, Barcelona, during my stay as a visiting
researcher, November 2004 - September 2005.
Thanks to Syneme at the University of Calgary for providing financial
support for the 1.1.0 update, December 2012 - March 2013.
See the file CHANGES for information about recent updates.
See the file LICENSE for information about distributing and using this code.
###

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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;
try{
// configure the master fd_set for select()
// configure the master fd_set for select()
fd_set masterfds, tempfds;
FD_ZERO( &masterfds );
FD_ZERO( &tempfds );
// 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 );
// 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];
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( fdmax < i->second->impl_->Socket() )
fdmax = i->second->impl_->Socket();
FD_SET( i->second->impl_->Socket(), &masterfds );
}
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;
// 1000000 microseconds in a second
timeout.tv_sec = (long)(timeoutMs * .001);
timeout.tv_usec = (long)((timeoutMs - (timeout.tv_sec * 1000)) * 1000);
timeoutPtr = &timeout;
}
struct timeval *timeoutPtr = 0;
if( !timerQueue_.empty() ){
double timeoutMs = timerQueue_.front().first - GetCurrentTimeMs();
if( timeoutMs < 0 )
timeoutMs = 0;
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( break_ )
break;
if( FD_ISSET( breakPipe_[0], &tempfds ) ){
// clear pending data from the asynchronous break pipe
char c;
read( breakPipe_[0], &c, 1 );
}
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()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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';
os << " " << s;
size_t len = std::strlen( timeString );
// -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 << "[" << m.AddressPattern();
os << "[";
if( m.AddressPatternIsUInt32() )
os << m.AddressPatternAsUInt32();
else
os << m.AddressPattern();
bool first = true;
for( ReceivedMessage::const_iterator i = m.ArgumentsBegin();
i != m.ArgumentsEnd(); ++i ){
if( first ){

View File

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

View File

@@ -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,50 +418,88 @@ 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:
case FALSE_TYPE_TAG:
case NIL_TYPE_TAG:
case INFINITUM_TYPE_TAG:
// zero length
break;
@@ -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" );

View File

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

View File

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

View File

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