mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-14 03:39:57 +01:00
Update to OSCPack v1.1
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
oscpack -- Open Sound Control packet manipulation library
|
||||
http://www.audiomulch.com/~rossb/oscpack
|
||||
oscpack -- Open Sound Control (OSC) packet manipulation library
|
||||
http://www.rossbencina.com/code/oscpack
|
||||
|
||||
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
|
||||
Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
@@ -15,10 +15,6 @@
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
requested to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
@@ -27,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" );
|
||||
|
||||
|
||||
Reference in New Issue
Block a user