mirror of
https://github.com/storytold/UE4-OSC.git
synced 2026-10-23 08:05:29 +00:00
replace exceptions with error code (mobile compilation)
This commit is contained in:
@@ -38,8 +38,6 @@ namespace UnrealBuildTool.Rules
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
bEnableExceptions = true;
|
|
||||||
|
|
||||||
if (Target.Type.HasValue && TargetRules.IsEditorType(Target.Type.Value))
|
if (Target.Type.HasValue && TargetRules.IsEditorType(Target.Type.Value))
|
||||||
{
|
{
|
||||||
Definitions.Add("OSC_EDITOR_BUILD=1");
|
Definitions.Add("OSC_EDITOR_BUILD=1");
|
||||||
|
|||||||
@@ -167,9 +167,21 @@ void UOscFunctionLibrary::SendOsc(FName Address, const TArray<FOscDataElemStruct
|
|||||||
{
|
{
|
||||||
output << elem.AsStringValue().GetPlainANSIString();
|
output << elem.AsStringValue().GetPlainANSIString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(output.State() != osc::SUCCESS)
|
||||||
|
{
|
||||||
|
UE_LOG(LogOSC, Error, TEXT("OSC Send Message Error: %s"), osc::errorString(output.State()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
output << osc::EndMessage;
|
output << osc::EndMessage;
|
||||||
|
|
||||||
|
if(output.State() != osc::SUCCESS)
|
||||||
|
{
|
||||||
|
UE_LOG(LogOSC, Error, TEXT("OSC Send Message Error: %s"), osc::errorString(output.State()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
check(reinterpret_cast<const void *>(buffer) == reinterpret_cast<const void *>(output.Data()));
|
check(reinterpret_cast<const void *>(buffer) == reinterpret_cast<const void *>(output.Data()));
|
||||||
GetMutableDefault<UOscSettings>()->Send(buffer, output.Size(), TargetIndex);
|
GetMutableDefault<UOscSettings>()->Send(buffer, output.Size(), TargetIndex);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
#ifndef INCLUDED_OSCPACK_OSCEXCEPTION_H
|
|
||||||
#define INCLUDED_OSCPACK_OSCEXCEPTION_H
|
|
||||||
|
|
||||||
#include <exception>
|
|
||||||
|
|
||||||
namespace osc{
|
|
||||||
|
|
||||||
class Exception : public std::exception {
|
|
||||||
const char *what_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Exception() throw() {}
|
|
||||||
Exception( const Exception& src ) throw()
|
|
||||||
: std::exception( src )
|
|
||||||
, what_( src.what_ ) {}
|
|
||||||
Exception( const char *w ) throw()
|
|
||||||
: what_( w ) {}
|
|
||||||
Exception& operator=( const Exception& src ) throw()
|
|
||||||
{ what_ = src.what_; return *this; }
|
|
||||||
virtual ~Exception() throw() {}
|
|
||||||
virtual const char* what() const throw() { return what_; }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace osc
|
|
||||||
|
|
||||||
#endif /* INCLUDED_OSCPACK_OSCEXCEPTION_H */
|
|
||||||
@@ -163,6 +163,7 @@ OutboundPacketStream::OutboundPacketStream( char *buffer, std::size_t capacity )
|
|||||||
, argumentCurrent_( data_ )
|
, argumentCurrent_( data_ )
|
||||||
, elementSizePtr_( 0 )
|
, elementSizePtr_( 0 )
|
||||||
, messageIsInProgress_( false )
|
, messageIsInProgress_( false )
|
||||||
|
, state_( SUCCESS )
|
||||||
{
|
{
|
||||||
// sanity check integer types declared in OscTypes.h
|
// sanity check integer types declared in OscTypes.h
|
||||||
// you'll need to fix OscTypes.h if any of these asserts fail
|
// you'll need to fix OscTypes.h if any of these asserts fail
|
||||||
@@ -236,34 +237,30 @@ bool OutboundPacketStream::ElementSizeSlotRequired() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OutboundPacketStream::CheckForAvailableBundleSpace()
|
Errors OutboundPacketStream::CheckForAvailableBundleSpace()
|
||||||
{
|
{
|
||||||
std::size_t required = Size() + ((ElementSizeSlotRequired())?4:0) + 16;
|
std::size_t required = Size() + ((ElementSizeSlotRequired())?4:0) + 16;
|
||||||
|
return (required > Capacity()) ? OUT_OF_BUFFER_MEMORY_ERROR : SUCCESS;
|
||||||
if( required > Capacity() )
|
|
||||||
throw OutOfBufferMemoryException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OutboundPacketStream::CheckForAvailableMessageSpace( const char *addressPattern )
|
Errors OutboundPacketStream::CheckForAvailableMessageSpace( const char *addressPattern )
|
||||||
{
|
{
|
||||||
// plus 4 for at least four bytes of type tag
|
// plus 4 for at least four bytes of type tag
|
||||||
std::size_t required = Size() + ((ElementSizeSlotRequired())?4:0)
|
std::size_t required = Size() + ((ElementSizeSlotRequired())?4:0)
|
||||||
+ RoundUp4(std::strlen(addressPattern) + 1) + 4;
|
+ RoundUp4(std::strlen(addressPattern) + 1) + 4;
|
||||||
|
|
||||||
if( required > Capacity() )
|
return (required > Capacity()) ? OUT_OF_BUFFER_MEMORY_ERROR : SUCCESS;
|
||||||
throw OutOfBufferMemoryException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OutboundPacketStream::CheckForAvailableArgumentSpace( std::size_t argumentLength )
|
Errors OutboundPacketStream::CheckForAvailableArgumentSpace( std::size_t argumentLength )
|
||||||
{
|
{
|
||||||
// plus three for extra type tag, comma and null terminator
|
// plus three for extra type tag, comma and null terminator
|
||||||
std::size_t required = (argumentCurrent_ - data_) + argumentLength
|
std::size_t required = (argumentCurrent_ - data_) + argumentLength
|
||||||
+ RoundUp4( (end_ - typeTagsCurrent_) + 3 );
|
+ RoundUp4( (end_ - typeTagsCurrent_) + 3 );
|
||||||
|
|
||||||
if( required > Capacity() )
|
return (required > Capacity()) ? OUT_OF_BUFFER_MEMORY_ERROR : SUCCESS;
|
||||||
throw OutOfBufferMemoryException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -274,6 +271,7 @@ void OutboundPacketStream::Clear()
|
|||||||
argumentCurrent_ = data_;
|
argumentCurrent_ = data_;
|
||||||
elementSizePtr_ = 0;
|
elementSizePtr_ = 0;
|
||||||
messageIsInProgress_ = false;
|
messageIsInProgress_ = false;
|
||||||
|
state_ = SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -322,18 +320,19 @@ bool OutboundPacketStream::IsBundleInProgress() const
|
|||||||
|
|
||||||
OutboundPacketStream& OutboundPacketStream::operator<<( const BundleInitiator& rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( const BundleInitiator& rhs )
|
||||||
{
|
{
|
||||||
if( IsMessageInProgress() )
|
check( !IsMessageInProgress() )
|
||||||
throw MessageInProgressException();
|
|
||||||
|
|
||||||
CheckForAvailableBundleSpace();
|
state_ = CheckForAvailableBundleSpace();
|
||||||
|
if(state_ == SUCCESS)
|
||||||
|
{
|
||||||
|
messageCursor_ = BeginElement( messageCursor_ );
|
||||||
|
|
||||||
messageCursor_ = BeginElement( messageCursor_ );
|
std::memcpy( messageCursor_, "#bundle\0", 8 );
|
||||||
|
FromUInt64( messageCursor_ + 8, rhs.timeTag );
|
||||||
|
|
||||||
std::memcpy( messageCursor_, "#bundle\0", 8 );
|
messageCursor_ += 16;
|
||||||
FromUInt64( messageCursor_ + 8, rhs.timeTag );
|
argumentCurrent_ = messageCursor_;
|
||||||
|
}
|
||||||
messageCursor_ += 16;
|
|
||||||
argumentCurrent_ = messageCursor_;
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -343,10 +342,8 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const BundleTerminator&
|
|||||||
{
|
{
|
||||||
(void) rhs;
|
(void) rhs;
|
||||||
|
|
||||||
if( !IsBundleInProgress() )
|
check( IsBundleInProgress() )
|
||||||
throw BundleNotInProgressException();
|
check( !IsMessageInProgress() )
|
||||||
if( IsMessageInProgress() )
|
|
||||||
throw MessageInProgressException();
|
|
||||||
|
|
||||||
EndElement( messageCursor_ );
|
EndElement( messageCursor_ );
|
||||||
|
|
||||||
@@ -356,29 +353,31 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const BundleTerminator&
|
|||||||
|
|
||||||
OutboundPacketStream& OutboundPacketStream::operator<<( const BeginMessage& rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( const BeginMessage& rhs )
|
||||||
{
|
{
|
||||||
if( IsMessageInProgress() )
|
check( !IsMessageInProgress() )
|
||||||
throw MessageInProgressException();
|
|
||||||
|
|
||||||
CheckForAvailableMessageSpace( rhs.addressPattern );
|
state_ = CheckForAvailableMessageSpace( rhs.addressPattern );
|
||||||
|
|
||||||
messageCursor_ = BeginElement( messageCursor_ );
|
if(state_ == SUCCESS)
|
||||||
|
{
|
||||||
|
messageCursor_ = BeginElement( messageCursor_ );
|
||||||
|
|
||||||
std::strcpy( messageCursor_, rhs.addressPattern );
|
std::strcpy( messageCursor_, rhs.addressPattern );
|
||||||
std::size_t rhsLength = std::strlen(rhs.addressPattern);
|
std::size_t rhsLength = std::strlen(rhs.addressPattern);
|
||||||
messageCursor_ += rhsLength + 1;
|
messageCursor_ += rhsLength + 1;
|
||||||
|
|
||||||
// zero pad to 4-byte boundary
|
// zero pad to 4-byte boundary
|
||||||
std::size_t i = rhsLength + 1;
|
std::size_t i = rhsLength + 1;
|
||||||
while( i & 0x3 ){
|
while( i & 0x3 ){
|
||||||
*messageCursor_++ = '\0';
|
*messageCursor_++ = '\0';
|
||||||
++i;
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
argumentCurrent_ = messageCursor_;
|
||||||
|
typeTagsCurrent_ = end_;
|
||||||
|
|
||||||
|
messageIsInProgress_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
argumentCurrent_ = messageCursor_;
|
|
||||||
typeTagsCurrent_ = end_;
|
|
||||||
|
|
||||||
messageIsInProgress_ = true;
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,8 +386,7 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const MessageTerminator&
|
|||||||
{
|
{
|
||||||
(void) rhs;
|
(void) rhs;
|
||||||
|
|
||||||
if( !IsMessageInProgress() )
|
check( IsMessageInProgress() )
|
||||||
throw MessageNotInProgressException();
|
|
||||||
|
|
||||||
std::size_t typeTagsCount = end_ - typeTagsCurrent_;
|
std::size_t typeTagsCount = end_ - typeTagsCurrent_;
|
||||||
|
|
||||||
@@ -438,9 +436,11 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const MessageTerminator&
|
|||||||
|
|
||||||
OutboundPacketStream& OutboundPacketStream::operator<<( bool rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( bool rhs )
|
||||||
{
|
{
|
||||||
CheckForAvailableArgumentSpace(0);
|
state_ = CheckForAvailableArgumentSpace(0);
|
||||||
|
if(state_ == SUCCESS)
|
||||||
*(--typeTagsCurrent_) = (char)((rhs) ? TRUE_TYPE_TAG : FALSE_TYPE_TAG);
|
{
|
||||||
|
*(--typeTagsCurrent_) = (char)((rhs) ? TRUE_TYPE_TAG : FALSE_TYPE_TAG);
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -449,9 +449,11 @@ OutboundPacketStream& OutboundPacketStream::operator<<( bool rhs )
|
|||||||
OutboundPacketStream& OutboundPacketStream::operator<<( const NilType& rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( const NilType& rhs )
|
||||||
{
|
{
|
||||||
(void) rhs;
|
(void) rhs;
|
||||||
CheckForAvailableArgumentSpace(0);
|
state_ = CheckForAvailableArgumentSpace(0);
|
||||||
|
if(state_ == SUCCESS)
|
||||||
*(--typeTagsCurrent_) = NIL_TYPE_TAG;
|
{
|
||||||
|
*(--typeTagsCurrent_) = NIL_TYPE_TAG;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -460,9 +462,11 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const NilType& rhs )
|
|||||||
OutboundPacketStream& OutboundPacketStream::operator<<( const InfinitumType& rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( const InfinitumType& rhs )
|
||||||
{
|
{
|
||||||
(void) rhs;
|
(void) rhs;
|
||||||
CheckForAvailableArgumentSpace(0);
|
state_ = CheckForAvailableArgumentSpace(0);
|
||||||
|
if(state_ == SUCCESS)
|
||||||
*(--typeTagsCurrent_) = INFINITUM_TYPE_TAG;
|
{
|
||||||
|
*(--typeTagsCurrent_) = INFINITUM_TYPE_TAG;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -470,11 +474,13 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const InfinitumType& rhs
|
|||||||
|
|
||||||
OutboundPacketStream& OutboundPacketStream::operator<<( int32 rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( int32 rhs )
|
||||||
{
|
{
|
||||||
CheckForAvailableArgumentSpace(4);
|
state_ = CheckForAvailableArgumentSpace(4);
|
||||||
|
if(state_ == SUCCESS)
|
||||||
*(--typeTagsCurrent_) = INT32_TYPE_TAG;
|
{
|
||||||
FromInt32( argumentCurrent_, rhs );
|
*(--typeTagsCurrent_) = INT32_TYPE_TAG;
|
||||||
argumentCurrent_ += 4;
|
FromInt32( argumentCurrent_, rhs );
|
||||||
|
argumentCurrent_ += 4;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -482,27 +488,29 @@ OutboundPacketStream& OutboundPacketStream::operator<<( int32 rhs )
|
|||||||
|
|
||||||
OutboundPacketStream& OutboundPacketStream::operator<<( float rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( float rhs )
|
||||||
{
|
{
|
||||||
CheckForAvailableArgumentSpace(4);
|
state_ = CheckForAvailableArgumentSpace(4);
|
||||||
|
if(state_ == SUCCESS)
|
||||||
*(--typeTagsCurrent_) = FLOAT_TYPE_TAG;
|
{
|
||||||
|
*(--typeTagsCurrent_) = FLOAT_TYPE_TAG;
|
||||||
|
|
||||||
#ifdef OSC_HOST_LITTLE_ENDIAN
|
#ifdef OSC_HOST_LITTLE_ENDIAN
|
||||||
union{
|
union{
|
||||||
float f;
|
float f;
|
||||||
char c[4];
|
char c[4];
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
u.f = rhs;
|
u.f = rhs;
|
||||||
|
|
||||||
argumentCurrent_[3] = u.c[0];
|
argumentCurrent_[3] = u.c[0];
|
||||||
argumentCurrent_[2] = u.c[1];
|
argumentCurrent_[2] = u.c[1];
|
||||||
argumentCurrent_[1] = u.c[2];
|
argumentCurrent_[1] = u.c[2];
|
||||||
argumentCurrent_[0] = u.c[3];
|
argumentCurrent_[0] = u.c[3];
|
||||||
#else
|
#else
|
||||||
*reinterpret_cast<float*>(argumentCurrent_) = rhs;
|
*reinterpret_cast<float*>(argumentCurrent_) = rhs;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
argumentCurrent_ += 4;
|
argumentCurrent_ += 4;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -510,11 +518,13 @@ OutboundPacketStream& OutboundPacketStream::operator<<( float rhs )
|
|||||||
|
|
||||||
OutboundPacketStream& OutboundPacketStream::operator<<( char rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( char rhs )
|
||||||
{
|
{
|
||||||
CheckForAvailableArgumentSpace(4);
|
state_ = CheckForAvailableArgumentSpace(4);
|
||||||
|
if(state_ == SUCCESS)
|
||||||
*(--typeTagsCurrent_) = CHAR_TYPE_TAG;
|
{
|
||||||
FromInt32( argumentCurrent_, rhs );
|
*(--typeTagsCurrent_) = CHAR_TYPE_TAG;
|
||||||
argumentCurrent_ += 4;
|
FromInt32( argumentCurrent_, rhs );
|
||||||
|
argumentCurrent_ += 4;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -522,11 +532,13 @@ OutboundPacketStream& OutboundPacketStream::operator<<( char rhs )
|
|||||||
|
|
||||||
OutboundPacketStream& OutboundPacketStream::operator<<( const RgbaColor& rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( const RgbaColor& rhs )
|
||||||
{
|
{
|
||||||
CheckForAvailableArgumentSpace(4);
|
state_ = CheckForAvailableArgumentSpace(4);
|
||||||
|
if(state_ == SUCCESS)
|
||||||
*(--typeTagsCurrent_) = RGBA_COLOR_TYPE_TAG;
|
{
|
||||||
FromUInt32( argumentCurrent_, rhs );
|
*(--typeTagsCurrent_) = RGBA_COLOR_TYPE_TAG;
|
||||||
argumentCurrent_ += 4;
|
FromUInt32( argumentCurrent_, rhs );
|
||||||
|
argumentCurrent_ += 4;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -534,11 +546,13 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const RgbaColor& rhs )
|
|||||||
|
|
||||||
OutboundPacketStream& OutboundPacketStream::operator<<( const MidiMessage& rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( const MidiMessage& rhs )
|
||||||
{
|
{
|
||||||
CheckForAvailableArgumentSpace(4);
|
state_ = CheckForAvailableArgumentSpace(4);
|
||||||
|
if(state_ == SUCCESS)
|
||||||
*(--typeTagsCurrent_) = MIDI_MESSAGE_TYPE_TAG;
|
{
|
||||||
FromUInt32( argumentCurrent_, rhs );
|
*(--typeTagsCurrent_) = MIDI_MESSAGE_TYPE_TAG;
|
||||||
argumentCurrent_ += 4;
|
FromUInt32( argumentCurrent_, rhs );
|
||||||
|
argumentCurrent_ += 4;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -546,11 +560,13 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const MidiMessage& rhs )
|
|||||||
|
|
||||||
OutboundPacketStream& OutboundPacketStream::operator<<( int64 rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( int64 rhs )
|
||||||
{
|
{
|
||||||
CheckForAvailableArgumentSpace(8);
|
state_ = CheckForAvailableArgumentSpace(8);
|
||||||
|
if(state_ == SUCCESS)
|
||||||
*(--typeTagsCurrent_) = INT64_TYPE_TAG;
|
{
|
||||||
FromInt64( argumentCurrent_, rhs );
|
*(--typeTagsCurrent_) = INT64_TYPE_TAG;
|
||||||
argumentCurrent_ += 8;
|
FromInt64( argumentCurrent_, rhs );
|
||||||
|
argumentCurrent_ += 8;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -558,11 +574,13 @@ OutboundPacketStream& OutboundPacketStream::operator<<( int64 rhs )
|
|||||||
|
|
||||||
OutboundPacketStream& OutboundPacketStream::operator<<( const TimeTag& rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( const TimeTag& rhs )
|
||||||
{
|
{
|
||||||
CheckForAvailableArgumentSpace(8);
|
state_ = CheckForAvailableArgumentSpace(8);
|
||||||
|
if(state_ == SUCCESS)
|
||||||
*(--typeTagsCurrent_) = TIME_TAG_TYPE_TAG;
|
{
|
||||||
FromUInt64( argumentCurrent_, rhs );
|
*(--typeTagsCurrent_) = TIME_TAG_TYPE_TAG;
|
||||||
argumentCurrent_ += 8;
|
FromUInt64( argumentCurrent_, rhs );
|
||||||
|
argumentCurrent_ += 8;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -570,31 +588,33 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const TimeTag& rhs )
|
|||||||
|
|
||||||
OutboundPacketStream& OutboundPacketStream::operator<<( double rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( double rhs )
|
||||||
{
|
{
|
||||||
CheckForAvailableArgumentSpace(8);
|
state_ = CheckForAvailableArgumentSpace(8);
|
||||||
|
if(state_ == SUCCESS)
|
||||||
*(--typeTagsCurrent_) = DOUBLE_TYPE_TAG;
|
{
|
||||||
|
*(--typeTagsCurrent_) = DOUBLE_TYPE_TAG;
|
||||||
|
|
||||||
#ifdef OSC_HOST_LITTLE_ENDIAN
|
#ifdef OSC_HOST_LITTLE_ENDIAN
|
||||||
union{
|
union{
|
||||||
double f;
|
double f;
|
||||||
char c[8];
|
char c[8];
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
u.f = rhs;
|
u.f = rhs;
|
||||||
|
|
||||||
argumentCurrent_[7] = u.c[0];
|
argumentCurrent_[7] = u.c[0];
|
||||||
argumentCurrent_[6] = u.c[1];
|
argumentCurrent_[6] = u.c[1];
|
||||||
argumentCurrent_[5] = u.c[2];
|
argumentCurrent_[5] = u.c[2];
|
||||||
argumentCurrent_[4] = u.c[3];
|
argumentCurrent_[4] = u.c[3];
|
||||||
argumentCurrent_[3] = u.c[4];
|
argumentCurrent_[3] = u.c[4];
|
||||||
argumentCurrent_[2] = u.c[5];
|
argumentCurrent_[2] = u.c[5];
|
||||||
argumentCurrent_[1] = u.c[6];
|
argumentCurrent_[1] = u.c[6];
|
||||||
argumentCurrent_[0] = u.c[7];
|
argumentCurrent_[0] = u.c[7];
|
||||||
#else
|
#else
|
||||||
*reinterpret_cast<double*>(argumentCurrent_) = rhs;
|
*reinterpret_cast<double*>(argumentCurrent_) = rhs;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
argumentCurrent_ += 8;
|
argumentCurrent_ += 8;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -602,18 +622,20 @@ OutboundPacketStream& OutboundPacketStream::operator<<( double rhs )
|
|||||||
|
|
||||||
OutboundPacketStream& OutboundPacketStream::operator<<( const char *rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( const char *rhs )
|
||||||
{
|
{
|
||||||
CheckForAvailableArgumentSpace( RoundUp4(std::strlen(rhs) + 1) );
|
state_ = CheckForAvailableArgumentSpace( RoundUp4(std::strlen(rhs) + 1) );
|
||||||
|
if(state_ == SUCCESS)
|
||||||
|
{
|
||||||
|
*(--typeTagsCurrent_) = STRING_TYPE_TAG;
|
||||||
|
std::strcpy( argumentCurrent_, rhs );
|
||||||
|
std::size_t rhsLength = std::strlen(rhs);
|
||||||
|
argumentCurrent_ += rhsLength + 1;
|
||||||
|
|
||||||
*(--typeTagsCurrent_) = STRING_TYPE_TAG;
|
// zero pad to 4-byte boundary
|
||||||
std::strcpy( argumentCurrent_, rhs );
|
std::size_t i = rhsLength + 1;
|
||||||
std::size_t rhsLength = std::strlen(rhs);
|
while( i & 0x3 ){
|
||||||
argumentCurrent_ += rhsLength + 1;
|
*argumentCurrent_++ = '\0';
|
||||||
|
++i;
|
||||||
// zero pad to 4-byte boundary
|
}
|
||||||
std::size_t i = rhsLength + 1;
|
|
||||||
while( i & 0x3 ){
|
|
||||||
*argumentCurrent_++ = '\0';
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@@ -622,18 +644,20 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const char *rhs )
|
|||||||
|
|
||||||
OutboundPacketStream& OutboundPacketStream::operator<<( const Symbol& rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( const Symbol& rhs )
|
||||||
{
|
{
|
||||||
CheckForAvailableArgumentSpace( RoundUp4(std::strlen(rhs) + 1) );
|
state_ = CheckForAvailableArgumentSpace( RoundUp4(std::strlen(rhs) + 1) );
|
||||||
|
if(state_ == SUCCESS)
|
||||||
|
{
|
||||||
|
*(--typeTagsCurrent_) = SYMBOL_TYPE_TAG;
|
||||||
|
std::strcpy( argumentCurrent_, rhs );
|
||||||
|
std::size_t rhsLength = std::strlen(rhs);
|
||||||
|
argumentCurrent_ += rhsLength + 1;
|
||||||
|
|
||||||
*(--typeTagsCurrent_) = SYMBOL_TYPE_TAG;
|
// zero pad to 4-byte boundary
|
||||||
std::strcpy( argumentCurrent_, rhs );
|
std::size_t i = rhsLength + 1;
|
||||||
std::size_t rhsLength = std::strlen(rhs);
|
while( i & 0x3 ){
|
||||||
argumentCurrent_ += rhsLength + 1;
|
*argumentCurrent_++ = '\0';
|
||||||
|
++i;
|
||||||
// zero pad to 4-byte boundary
|
}
|
||||||
std::size_t i = rhsLength + 1;
|
|
||||||
while( i & 0x3 ){
|
|
||||||
*argumentCurrent_++ = '\0';
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@@ -642,20 +666,22 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const Symbol& rhs )
|
|||||||
|
|
||||||
OutboundPacketStream& OutboundPacketStream::operator<<( const Blob& rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( const Blob& rhs )
|
||||||
{
|
{
|
||||||
CheckForAvailableArgumentSpace( 4 + RoundUp4(rhs.size) );
|
state_ = CheckForAvailableArgumentSpace( 4 + RoundUp4(rhs.size) );
|
||||||
|
if(state_ == SUCCESS)
|
||||||
*(--typeTagsCurrent_) = BLOB_TYPE_TAG;
|
{
|
||||||
FromUInt32( argumentCurrent_, rhs.size );
|
*(--typeTagsCurrent_) = BLOB_TYPE_TAG;
|
||||||
argumentCurrent_ += 4;
|
FromUInt32( argumentCurrent_, rhs.size );
|
||||||
|
argumentCurrent_ += 4;
|
||||||
|
|
||||||
std::memcpy( argumentCurrent_, rhs.data, rhs.size );
|
std::memcpy( argumentCurrent_, rhs.data, rhs.size );
|
||||||
argumentCurrent_ += rhs.size;
|
argumentCurrent_ += rhs.size;
|
||||||
|
|
||||||
// zero pad to 4-byte boundary
|
// zero pad to 4-byte boundary
|
||||||
unsigned long i = rhs.size;
|
unsigned long i = rhs.size;
|
||||||
while( i & 0x3 ){
|
while( i & 0x3 ){
|
||||||
*argumentCurrent_++ = '\0';
|
*argumentCurrent_++ = '\0';
|
||||||
++i;
|
++i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@@ -664,9 +690,11 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const Blob& rhs )
|
|||||||
OutboundPacketStream& OutboundPacketStream::operator<<( const ArrayInitiator& rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( const ArrayInitiator& rhs )
|
||||||
{
|
{
|
||||||
(void) rhs;
|
(void) rhs;
|
||||||
CheckForAvailableArgumentSpace(0);
|
state_ = CheckForAvailableArgumentSpace(0);
|
||||||
|
if(state_ == SUCCESS)
|
||||||
*(--typeTagsCurrent_) = ARRAY_BEGIN_TYPE_TAG;
|
{
|
||||||
|
*(--typeTagsCurrent_) = ARRAY_BEGIN_TYPE_TAG;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -674,9 +702,11 @@ OutboundPacketStream& OutboundPacketStream::operator<<( const ArrayInitiator& rh
|
|||||||
OutboundPacketStream& OutboundPacketStream::operator<<( const ArrayTerminator& rhs )
|
OutboundPacketStream& OutboundPacketStream::operator<<( const ArrayTerminator& rhs )
|
||||||
{
|
{
|
||||||
(void) rhs;
|
(void) rhs;
|
||||||
CheckForAvailableArgumentSpace(0);
|
state_ = CheckForAvailableArgumentSpace(0);
|
||||||
|
if(state_ == SUCCESS)
|
||||||
*(--typeTagsCurrent_) = ARRAY_END_TYPE_TAG;
|
{
|
||||||
|
*(--typeTagsCurrent_) = ARRAY_END_TYPE_TAG;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,44 +40,18 @@
|
|||||||
#include <cstring> // size_t
|
#include <cstring> // size_t
|
||||||
|
|
||||||
#include "OscTypes.h"
|
#include "OscTypes.h"
|
||||||
#include "OscException.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace osc{
|
namespace osc{
|
||||||
|
|
||||||
class OutOfBufferMemoryException : public Exception{
|
|
||||||
public:
|
|
||||||
OutOfBufferMemoryException( const char *w="out of buffer memory" )
|
|
||||||
: Exception( w ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class BundleNotInProgressException : public Exception{
|
|
||||||
public:
|
|
||||||
BundleNotInProgressException(
|
|
||||||
const char *w="call to EndBundle when bundle is not in progress" )
|
|
||||||
: Exception( w ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class MessageInProgressException : public Exception{
|
|
||||||
public:
|
|
||||||
MessageInProgressException(
|
|
||||||
const char *w="opening or closing bundle or message while message is in progress" )
|
|
||||||
: Exception( w ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class MessageNotInProgressException : public Exception{
|
|
||||||
public:
|
|
||||||
MessageNotInProgressException(
|
|
||||||
const char *w="call to EndMessage when message is not in progress" )
|
|
||||||
: Exception( w ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class OutboundPacketStream{
|
class OutboundPacketStream{
|
||||||
public:
|
public:
|
||||||
OutboundPacketStream( char *buffer, std::size_t capacity );
|
OutboundPacketStream( char *buffer, std::size_t capacity );
|
||||||
~OutboundPacketStream();
|
~OutboundPacketStream();
|
||||||
|
|
||||||
|
Errors State() const { return state_; }
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
std::size_t Capacity() const;
|
std::size_t Capacity() const;
|
||||||
@@ -130,9 +104,9 @@ private:
|
|||||||
void EndElement( char *endPtr );
|
void EndElement( char *endPtr );
|
||||||
|
|
||||||
bool ElementSizeSlotRequired() const;
|
bool ElementSizeSlotRequired() const;
|
||||||
void CheckForAvailableBundleSpace();
|
Errors CheckForAvailableBundleSpace();
|
||||||
void CheckForAvailableMessageSpace( const char *addressPattern );
|
Errors CheckForAvailableMessageSpace( const char *addressPattern );
|
||||||
void CheckForAvailableArgumentSpace( std::size_t argumentLength );
|
Errors CheckForAvailableArgumentSpace( std::size_t argumentLength );
|
||||||
|
|
||||||
char *data_;
|
char *data_;
|
||||||
char *end_;
|
char *end_;
|
||||||
@@ -147,6 +121,8 @@ private:
|
|||||||
uint32 *elementSizePtr_;
|
uint32 *elementSizePtr_;
|
||||||
|
|
||||||
bool messageIsInProgress_;
|
bool messageIsInProgress_;
|
||||||
|
|
||||||
|
Errors state_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace osc
|
} // namespace osc
|
||||||
|
|||||||
@@ -202,38 +202,44 @@ osc_bundle_element_size_t ReceivedBundleElement::Size() const
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
bool ReceivedMessageArgument::AsBool() const
|
bool ReceivedMessageArgument::AsBool(Errors & state) const
|
||||||
{
|
{
|
||||||
|
state = SUCCESS;
|
||||||
if( !typeTagPtr_ )
|
if( !typeTagPtr_ )
|
||||||
throw MissingArgumentException();
|
state = MISSING_ARGUMENT_ERROR;
|
||||||
else if( *typeTagPtr_ == TRUE_TYPE_TAG )
|
else if( *typeTagPtr_ == TRUE_TYPE_TAG )
|
||||||
return true;
|
return true;
|
||||||
else if( *typeTagPtr_ == FALSE_TYPE_TAG )
|
else if( *typeTagPtr_ == FALSE_TYPE_TAG )
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
throw WrongArgumentTypeException();
|
state = WRONG_ARGUMENT_TYPE_ERROR;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ReceivedMessageArgument::AsBoolUnchecked() const
|
bool ReceivedMessageArgument::AsBoolUnchecked(Errors & state) const
|
||||||
{
|
{
|
||||||
|
state = SUCCESS;
|
||||||
if( !typeTagPtr_ )
|
if( !typeTagPtr_ )
|
||||||
throw MissingArgumentException();
|
state = MISSING_ARGUMENT_ERROR;
|
||||||
else if( *typeTagPtr_ == TRUE_TYPE_TAG )
|
else if( *typeTagPtr_ == TRUE_TYPE_TAG )
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32 ReceivedMessageArgument::AsInt32() const
|
int32 ReceivedMessageArgument::AsInt32(Errors & state) const
|
||||||
{
|
{
|
||||||
|
state = SUCCESS;
|
||||||
if( !typeTagPtr_ )
|
if( !typeTagPtr_ )
|
||||||
throw MissingArgumentException();
|
state = MISSING_ARGUMENT_ERROR;
|
||||||
else if( *typeTagPtr_ == INT32_TYPE_TAG )
|
else if( *typeTagPtr_ == INT32_TYPE_TAG )
|
||||||
return AsInt32Unchecked();
|
return AsInt32Unchecked();
|
||||||
else
|
else
|
||||||
throw WrongArgumentTypeException();
|
state = WRONG_ARGUMENT_TYPE_ERROR;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -257,14 +263,16 @@ int32 ReceivedMessageArgument::AsInt32Unchecked() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float ReceivedMessageArgument::AsFloat() const
|
float ReceivedMessageArgument::AsFloat(Errors & state) const
|
||||||
{
|
{
|
||||||
|
state = SUCCESS;
|
||||||
if( !typeTagPtr_ )
|
if( !typeTagPtr_ )
|
||||||
throw MissingArgumentException();
|
state = MISSING_ARGUMENT_ERROR;
|
||||||
else if( *typeTagPtr_ == FLOAT_TYPE_TAG )
|
else if( *typeTagPtr_ == FLOAT_TYPE_TAG )
|
||||||
return AsFloatUnchecked();
|
return AsFloatUnchecked();
|
||||||
else
|
else
|
||||||
throw WrongArgumentTypeException();
|
state = WRONG_ARGUMENT_TYPE_ERROR;
|
||||||
|
return 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -288,14 +296,16 @@ float ReceivedMessageArgument::AsFloatUnchecked() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char ReceivedMessageArgument::AsChar() const
|
char ReceivedMessageArgument::AsChar(Errors & state) const
|
||||||
{
|
{
|
||||||
|
state = SUCCESS;
|
||||||
if( !typeTagPtr_ )
|
if( !typeTagPtr_ )
|
||||||
throw MissingArgumentException();
|
state = MISSING_ARGUMENT_ERROR;
|
||||||
else if( *typeTagPtr_ == CHAR_TYPE_TAG )
|
else if( *typeTagPtr_ == CHAR_TYPE_TAG )
|
||||||
return AsCharUnchecked();
|
return AsCharUnchecked();
|
||||||
else
|
else
|
||||||
throw WrongArgumentTypeException();
|
state = WRONG_ARGUMENT_TYPE_ERROR;
|
||||||
|
return '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -305,14 +315,16 @@ char ReceivedMessageArgument::AsCharUnchecked() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32 ReceivedMessageArgument::AsRgbaColor() const
|
uint32 ReceivedMessageArgument::AsRgbaColor(Errors & state) const
|
||||||
{
|
{
|
||||||
|
state = SUCCESS;
|
||||||
if( !typeTagPtr_ )
|
if( !typeTagPtr_ )
|
||||||
throw MissingArgumentException();
|
state = MISSING_ARGUMENT_ERROR;
|
||||||
else if( *typeTagPtr_ == RGBA_COLOR_TYPE_TAG )
|
else if( *typeTagPtr_ == RGBA_COLOR_TYPE_TAG )
|
||||||
return AsRgbaColorUnchecked();
|
return AsRgbaColorUnchecked();
|
||||||
else
|
else
|
||||||
throw WrongArgumentTypeException();
|
state = WRONG_ARGUMENT_TYPE_ERROR;
|
||||||
|
return 0u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -322,14 +334,16 @@ uint32 ReceivedMessageArgument::AsRgbaColorUnchecked() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32 ReceivedMessageArgument::AsMidiMessage() const
|
uint32 ReceivedMessageArgument::AsMidiMessage(Errors & state) const
|
||||||
{
|
{
|
||||||
|
state = SUCCESS;
|
||||||
if( !typeTagPtr_ )
|
if( !typeTagPtr_ )
|
||||||
throw MissingArgumentException();
|
state = MISSING_ARGUMENT_ERROR;
|
||||||
else if( *typeTagPtr_ == MIDI_MESSAGE_TYPE_TAG )
|
else if( *typeTagPtr_ == MIDI_MESSAGE_TYPE_TAG )
|
||||||
return AsMidiMessageUnchecked();
|
return AsMidiMessageUnchecked();
|
||||||
else
|
else
|
||||||
throw WrongArgumentTypeException();
|
state = WRONG_ARGUMENT_TYPE_ERROR;
|
||||||
|
return 0u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -339,14 +353,16 @@ uint32 ReceivedMessageArgument::AsMidiMessageUnchecked() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int64 ReceivedMessageArgument::AsInt64() const
|
int64 ReceivedMessageArgument::AsInt64(Errors & state) const
|
||||||
{
|
{
|
||||||
|
state = SUCCESS;
|
||||||
if( !typeTagPtr_ )
|
if( !typeTagPtr_ )
|
||||||
throw MissingArgumentException();
|
state = MISSING_ARGUMENT_ERROR;
|
||||||
else if( *typeTagPtr_ == INT64_TYPE_TAG )
|
else if( *typeTagPtr_ == INT64_TYPE_TAG )
|
||||||
return AsInt64Unchecked();
|
return AsInt64Unchecked();
|
||||||
else
|
else
|
||||||
throw WrongArgumentTypeException();
|
state = WRONG_ARGUMENT_TYPE_ERROR;
|
||||||
|
return 0LL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -356,14 +372,16 @@ int64 ReceivedMessageArgument::AsInt64Unchecked() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint64 ReceivedMessageArgument::AsTimeTag() const
|
uint64 ReceivedMessageArgument::AsTimeTag(Errors & state) const
|
||||||
{
|
{
|
||||||
|
state = SUCCESS;
|
||||||
if( !typeTagPtr_ )
|
if( !typeTagPtr_ )
|
||||||
throw MissingArgumentException();
|
state = MISSING_ARGUMENT_ERROR;
|
||||||
else if( *typeTagPtr_ == TIME_TAG_TYPE_TAG )
|
else if( *typeTagPtr_ == TIME_TAG_TYPE_TAG )
|
||||||
return AsTimeTagUnchecked();
|
return AsTimeTagUnchecked();
|
||||||
else
|
else
|
||||||
throw WrongArgumentTypeException();
|
state = WRONG_ARGUMENT_TYPE_ERROR;
|
||||||
|
return 0ULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -373,14 +391,16 @@ uint64 ReceivedMessageArgument::AsTimeTagUnchecked() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double ReceivedMessageArgument::AsDouble() const
|
double ReceivedMessageArgument::AsDouble(Errors & state) const
|
||||||
{
|
{
|
||||||
|
state = SUCCESS;
|
||||||
if( !typeTagPtr_ )
|
if( !typeTagPtr_ )
|
||||||
throw MissingArgumentException();
|
state = MISSING_ARGUMENT_ERROR;
|
||||||
else if( *typeTagPtr_ == DOUBLE_TYPE_TAG )
|
else if( *typeTagPtr_ == DOUBLE_TYPE_TAG )
|
||||||
return AsDoubleUnchecked();
|
return AsDoubleUnchecked();
|
||||||
else
|
else
|
||||||
throw WrongArgumentTypeException();
|
state = WRONG_ARGUMENT_TYPE_ERROR;
|
||||||
|
return 0.;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -408,55 +428,69 @@ double ReceivedMessageArgument::AsDoubleUnchecked() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char* ReceivedMessageArgument::AsString() const
|
const char* ReceivedMessageArgument::AsString(Errors & state) const
|
||||||
{
|
{
|
||||||
|
state = SUCCESS;
|
||||||
if( !typeTagPtr_ )
|
if( !typeTagPtr_ )
|
||||||
throw MissingArgumentException();
|
state = MISSING_ARGUMENT_ERROR;
|
||||||
else if( *typeTagPtr_ == STRING_TYPE_TAG )
|
else if( *typeTagPtr_ == STRING_TYPE_TAG )
|
||||||
return argumentPtr_;
|
return argumentPtr_;
|
||||||
else
|
else
|
||||||
throw WrongArgumentTypeException();
|
state = WRONG_ARGUMENT_TYPE_ERROR;
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char* ReceivedMessageArgument::AsSymbol() const
|
const char* ReceivedMessageArgument::AsSymbol(Errors & state) const
|
||||||
{
|
{
|
||||||
|
state = SUCCESS;
|
||||||
if( !typeTagPtr_ )
|
if( !typeTagPtr_ )
|
||||||
throw MissingArgumentException();
|
state = MISSING_ARGUMENT_ERROR;
|
||||||
else if( *typeTagPtr_ == SYMBOL_TYPE_TAG )
|
else if( *typeTagPtr_ == SYMBOL_TYPE_TAG )
|
||||||
return argumentPtr_;
|
return argumentPtr_;
|
||||||
else
|
else
|
||||||
throw WrongArgumentTypeException();
|
state = WRONG_ARGUMENT_TYPE_ERROR;
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ReceivedMessageArgument::AsBlob( const void*& data, osc_bundle_element_size_t& size ) const
|
void ReceivedMessageArgument::AsBlob( const void*& data, osc_bundle_element_size_t& size, Errors & state ) const
|
||||||
{
|
{
|
||||||
if( !typeTagPtr_ )
|
if( !typeTagPtr_ )
|
||||||
throw MissingArgumentException();
|
state = MISSING_ARGUMENT_ERROR;
|
||||||
else if( *typeTagPtr_ == BLOB_TYPE_TAG )
|
else if( *typeTagPtr_ == BLOB_TYPE_TAG )
|
||||||
AsBlobUnchecked( data, size );
|
AsBlobUnchecked( data, size, state );
|
||||||
else
|
else
|
||||||
throw WrongArgumentTypeException();
|
state = WRONG_ARGUMENT_TYPE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ReceivedMessageArgument::AsBlobUnchecked( const void*& data, osc_bundle_element_size_t& size ) const
|
void ReceivedMessageArgument::AsBlobUnchecked( const void*& data, osc_bundle_element_size_t& size, Errors & state ) const
|
||||||
{
|
{
|
||||||
// read blob size as an unsigned int then validate
|
// read blob size as an unsigned int then validate
|
||||||
osc_bundle_element_size_t sizeResult = (osc_bundle_element_size_t)ToUInt32( argumentPtr_ );
|
osc_bundle_element_size_t sizeResult = (osc_bundle_element_size_t)ToUInt32( argumentPtr_ );
|
||||||
if( !IsValidElementSizeValue(sizeResult) )
|
if( !IsValidElementSizeValue(sizeResult) )
|
||||||
throw MalformedMessageException("invalid blob size");
|
{
|
||||||
|
state = MALFORMED_MESSAGE_INVALID_BLOB_SIZE_ERROR;
|
||||||
size = sizeResult;
|
}
|
||||||
data = (void*)(argumentPtr_+ osc::OSC_SIZEOF_INT32);
|
else
|
||||||
|
{
|
||||||
|
state = SUCCESS;
|
||||||
|
size = sizeResult;
|
||||||
|
data = (void*)(argumentPtr_+ osc::OSC_SIZEOF_INT32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t ReceivedMessageArgument::ComputeArrayItemCount() const
|
std::size_t ReceivedMessageArgument::ComputeArrayItemCount(Errors & state) const
|
||||||
{
|
{
|
||||||
// it is only valid to call ComputeArrayItemCount when the argument is the array start marker
|
// it is only valid to call ComputeArrayItemCount when the argument is the array start marker
|
||||||
if( !IsArrayBegin() )
|
if( !IsArrayBegin() )
|
||||||
throw WrongArgumentTypeException();
|
{
|
||||||
|
state = WRONG_ARGUMENT_TYPE_ERROR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = SUCCESS;
|
||||||
|
|
||||||
std::size_t result = 0;
|
std::size_t result = 0;
|
||||||
unsigned int level = 0;
|
unsigned int level = 0;
|
||||||
@@ -561,6 +595,7 @@ void ReceivedMessageArgumentIterator::Advance()
|
|||||||
|
|
||||||
ReceivedMessage::ReceivedMessage( const ReceivedPacket& packet )
|
ReceivedMessage::ReceivedMessage( const ReceivedPacket& packet )
|
||||||
: addressPattern_( packet.Contents() )
|
: addressPattern_( packet.Contents() )
|
||||||
|
, state_( SUCCESS )
|
||||||
{
|
{
|
||||||
Init( packet.Contents(), packet.Size() );
|
Init( packet.Contents(), packet.Size() );
|
||||||
}
|
}
|
||||||
@@ -568,6 +603,7 @@ ReceivedMessage::ReceivedMessage( const ReceivedPacket& packet )
|
|||||||
|
|
||||||
ReceivedMessage::ReceivedMessage( const ReceivedBundleElement& bundleElement )
|
ReceivedMessage::ReceivedMessage( const ReceivedBundleElement& bundleElement )
|
||||||
: addressPattern_( bundleElement.Contents() )
|
: addressPattern_( bundleElement.Contents() )
|
||||||
|
, state_( SUCCESS )
|
||||||
{
|
{
|
||||||
Init( bundleElement.Contents(), bundleElement.Size() );
|
Init( bundleElement.Contents(), bundleElement.Size() );
|
||||||
}
|
}
|
||||||
@@ -588,20 +624,30 @@ uint32 ReceivedMessage::AddressPatternAsUInt32() const
|
|||||||
void ReceivedMessage::Init( const char *message, osc_bundle_element_size_t size )
|
void ReceivedMessage::Init( const char *message, osc_bundle_element_size_t size )
|
||||||
{
|
{
|
||||||
if( !IsValidElementSizeValue(size) )
|
if( !IsValidElementSizeValue(size) )
|
||||||
throw MalformedMessageException( "invalid message size" );
|
{
|
||||||
|
state_ = MALFORMED_MESSAGE_INVALID_SIZE_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( size == 0 )
|
if( size == 0 )
|
||||||
throw MalformedMessageException( "zero length messages not permitted" );
|
{
|
||||||
|
state_ = MALFORMED_MESSAGE_ZERO_SIZE_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( !IsMultipleOf4(size) )
|
if( !IsMultipleOf4(size) )
|
||||||
throw MalformedMessageException( "message size must be multiple of four" );
|
{
|
||||||
|
state_ = MALFORMED_MESSAGE_NOT_MULTIPLE_OF_4_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const char *end = message + size;
|
const char *end = message + size;
|
||||||
|
|
||||||
typeTagsBegin_ = FindStr4End( addressPattern_, end );
|
typeTagsBegin_ = FindStr4End( addressPattern_, end );
|
||||||
if( typeTagsBegin_ == 0 ){
|
if( typeTagsBegin_ == 0 ){
|
||||||
// address pattern was not terminated before end
|
// address pattern was not terminated before end
|
||||||
throw MalformedMessageException( "unterminated address pattern" );
|
state_ = MALFORMED_MESSAGE_UNTERMINATED_ADDRESS_PATTERN_ERROR;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( typeTagsBegin_ == end ){
|
if( typeTagsBegin_ == end ){
|
||||||
@@ -612,7 +658,10 @@ void ReceivedMessage::Init( const char *message, osc_bundle_element_size_t size
|
|||||||
|
|
||||||
}else{
|
}else{
|
||||||
if( *typeTagsBegin_ != ',' )
|
if( *typeTagsBegin_ != ',' )
|
||||||
throw MalformedMessageException( "type tags not present" );
|
{
|
||||||
|
state_ = MALFORMED_MESSAGE_NO_TYPE_TAGS_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( *(typeTagsBegin_ + 1) == '\0' ){
|
if( *(typeTagsBegin_ + 1) == '\0' ){
|
||||||
// zero length type tags
|
// zero length type tags
|
||||||
@@ -624,8 +673,10 @@ void ReceivedMessage::Init( const char *message, osc_bundle_element_size_t size
|
|||||||
// check that all arguments are present and well formed
|
// check that all arguments are present and well formed
|
||||||
|
|
||||||
arguments_ = FindStr4End( typeTagsBegin_, end );
|
arguments_ = FindStr4End( typeTagsBegin_, end );
|
||||||
if( arguments_ == 0 ){
|
if( arguments_ == 0 )
|
||||||
throw MalformedMessageException( "type tags were not terminated before end of message" );
|
{
|
||||||
|
state_ = MALFORMED_MESSAGE_UNTERMINATED_TYPE_TAGS_ERROR;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
++typeTagsBegin_; // advance past initial ','
|
++typeTagsBegin_; // advance past initial ','
|
||||||
@@ -663,10 +714,16 @@ void ReceivedMessage::Init( const char *message, osc_bundle_element_size_t size
|
|||||||
case MIDI_MESSAGE_TYPE_TAG:
|
case MIDI_MESSAGE_TYPE_TAG:
|
||||||
|
|
||||||
if( argument == end )
|
if( argument == end )
|
||||||
throw MalformedMessageException( "arguments exceed message size" );
|
{
|
||||||
|
state_ = MALFORMED_MESSAGE_ARGUMENT_EXCEED_MSG_SIZE_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
argument += 4;
|
argument += 4;
|
||||||
if( argument > end )
|
if( argument > end )
|
||||||
throw MalformedMessageException( "arguments exceed message size" );
|
{
|
||||||
|
state_ = MALFORMED_MESSAGE_ARGUMENT_EXCEED_MSG_SIZE_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INT64_TYPE_TAG:
|
case INT64_TYPE_TAG:
|
||||||
@@ -674,44 +731,66 @@ void ReceivedMessage::Init( const char *message, osc_bundle_element_size_t size
|
|||||||
case DOUBLE_TYPE_TAG:
|
case DOUBLE_TYPE_TAG:
|
||||||
|
|
||||||
if( argument == end )
|
if( argument == end )
|
||||||
throw MalformedMessageException( "arguments exceed message size" );
|
{
|
||||||
|
state_ = MALFORMED_MESSAGE_ARGUMENT_EXCEED_MSG_SIZE_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
argument += 8;
|
argument += 8;
|
||||||
if( argument > end )
|
if( argument > end )
|
||||||
throw MalformedMessageException( "arguments exceed message size" );
|
{
|
||||||
|
state_ = MALFORMED_MESSAGE_ARGUMENT_EXCEED_MSG_SIZE_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STRING_TYPE_TAG:
|
case STRING_TYPE_TAG:
|
||||||
case SYMBOL_TYPE_TAG:
|
case SYMBOL_TYPE_TAG:
|
||||||
|
|
||||||
if( argument == end )
|
if( argument == end )
|
||||||
throw MalformedMessageException( "arguments exceed message size" );
|
{
|
||||||
|
state_ = MALFORMED_MESSAGE_ARGUMENT_EXCEED_MSG_SIZE_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
argument = FindStr4End( argument, end );
|
argument = FindStr4End( argument, end );
|
||||||
if( argument == 0 )
|
if( argument == 0 )
|
||||||
throw MalformedMessageException( "unterminated string argument" );
|
{
|
||||||
|
state_ = MALFORMED_MESSAGE_UNTERMINATED_STRING_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLOB_TYPE_TAG:
|
case BLOB_TYPE_TAG:
|
||||||
{
|
{
|
||||||
if( argument + osc::OSC_SIZEOF_INT32 > end )
|
if( argument + osc::OSC_SIZEOF_INT32 > end )
|
||||||
MalformedMessageException( "arguments exceed message size" );
|
{
|
||||||
|
state_ = MALFORMED_MESSAGE_ARGUMENT_EXCEED_MSG_SIZE_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// treat blob size as an unsigned int for the purposes of this calculation
|
// treat blob size as an unsigned int for the purposes of this calculation
|
||||||
uint32 blobSize = ToUInt32( argument );
|
uint32 blobSize = ToUInt32( argument );
|
||||||
argument = argument + osc::OSC_SIZEOF_INT32 + RoundUp4( blobSize );
|
argument = argument + osc::OSC_SIZEOF_INT32 + RoundUp4( blobSize );
|
||||||
if( argument > end )
|
if( argument > end )
|
||||||
MalformedMessageException( "arguments exceed message size" );
|
{
|
||||||
|
state_ = MALFORMED_MESSAGE_ARGUMENT_EXCEED_MSG_SIZE_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw MalformedMessageException( "unknown type tag" );
|
state_ = MALFORMED_MESSAGE_UNKNOWN_TYPE_TAG_ERROR;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}while( *++typeTag != '\0' );
|
}while( *++typeTag != '\0' );
|
||||||
typeTagsEnd_ = typeTag;
|
typeTagsEnd_ = typeTag;
|
||||||
|
|
||||||
if( arrayLevel != 0 )
|
if( arrayLevel != 0 )
|
||||||
throw MalformedMessageException( "array was not terminated before end of message (expected ']' end of array tag)" );
|
{
|
||||||
|
state_ = MALFORMED_MESSAGE_UNTERMINATED_ARRAY_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// These invariants should be guaranteed by the above code.
|
// These invariants should be guaranteed by the above code.
|
||||||
@@ -728,6 +807,7 @@ void ReceivedMessage::Init( const char *message, osc_bundle_element_size_t size
|
|||||||
|
|
||||||
ReceivedBundle::ReceivedBundle( const ReceivedPacket& packet )
|
ReceivedBundle::ReceivedBundle( const ReceivedPacket& packet )
|
||||||
: elementCount_( 0 )
|
: elementCount_( 0 )
|
||||||
|
, state_( SUCCESS )
|
||||||
{
|
{
|
||||||
Init( packet.Contents(), packet.Size() );
|
Init( packet.Contents(), packet.Size() );
|
||||||
}
|
}
|
||||||
@@ -735,6 +815,7 @@ ReceivedBundle::ReceivedBundle( const ReceivedPacket& packet )
|
|||||||
|
|
||||||
ReceivedBundle::ReceivedBundle( const ReceivedBundleElement& bundleElement )
|
ReceivedBundle::ReceivedBundle( const ReceivedBundleElement& bundleElement )
|
||||||
: elementCount_( 0 )
|
: elementCount_( 0 )
|
||||||
|
, state_( SUCCESS )
|
||||||
{
|
{
|
||||||
Init( bundleElement.Contents(), bundleElement.Size() );
|
Init( bundleElement.Contents(), bundleElement.Size() );
|
||||||
}
|
}
|
||||||
@@ -744,13 +825,22 @@ void ReceivedBundle::Init( const char *bundle, osc_bundle_element_size_t size )
|
|||||||
{
|
{
|
||||||
|
|
||||||
if( !IsValidElementSizeValue(size) )
|
if( !IsValidElementSizeValue(size) )
|
||||||
throw MalformedBundleException( "invalid bundle size" );
|
{
|
||||||
|
state_ = MALFORMED_BUNDLE_INVALID_SIZE_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( size < 16 )
|
if( size < 16 )
|
||||||
throw MalformedBundleException( "packet too short for bundle" );
|
{
|
||||||
|
state_ = MALFORMED_BUNDLE_TOO_SHORT_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( !IsMultipleOf4(size) )
|
if( !IsMultipleOf4(size) )
|
||||||
throw MalformedBundleException( "bundle size must be multiple of four" );
|
{
|
||||||
|
state_ = MALFORMED_BUNDLE_NOT_MULTIPLE_OF_4_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( bundle[0] != '#'
|
if( bundle[0] != '#'
|
||||||
|| bundle[1] != 'b'
|
|| bundle[1] != 'b'
|
||||||
@@ -760,7 +850,10 @@ void ReceivedBundle::Init( const char *bundle, osc_bundle_element_size_t size )
|
|||||||
|| bundle[5] != 'l'
|
|| bundle[5] != 'l'
|
||||||
|| bundle[6] != 'e'
|
|| bundle[6] != 'e'
|
||||||
|| bundle[7] != '\0' )
|
|| bundle[7] != '\0' )
|
||||||
throw MalformedBundleException( "bad bundle address pattern" );
|
{
|
||||||
|
state_ = MALFORMED_BUNDLE_INVALID_ADDRESS_PATTERN_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
end_ = bundle + size;
|
end_ = bundle + size;
|
||||||
|
|
||||||
@@ -770,22 +863,33 @@ void ReceivedBundle::Init( const char *bundle, osc_bundle_element_size_t size )
|
|||||||
|
|
||||||
while( p < end_ ){
|
while( p < end_ ){
|
||||||
if( p + osc::OSC_SIZEOF_INT32 > end_ )
|
if( p + osc::OSC_SIZEOF_INT32 > end_ )
|
||||||
throw MalformedBundleException( "packet too short for elementSize" );
|
{
|
||||||
|
state_ = MALFORMED_BUNDLE_TOO_SHORT_FOR_ELEMENT_SIZE_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// treat element size as an unsigned int for the purposes of this calculation
|
// treat element size as an unsigned int for the purposes of this calculation
|
||||||
uint32 elementSize = ToUInt32( p );
|
uint32 elementSize = ToUInt32( p );
|
||||||
if( (elementSize & ((uint32)0x03)) != 0 )
|
if( (elementSize & ((uint32)0x03)) != 0 )
|
||||||
throw MalformedBundleException( "bundle element size must be multiple of four" );
|
{
|
||||||
|
state_ = MALFORMED_BUNDLE_ELEMENT_NOT_MULTIPLE_OF_4_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
p += osc::OSC_SIZEOF_INT32 + elementSize;
|
p += osc::OSC_SIZEOF_INT32 + elementSize;
|
||||||
if( p > end_ )
|
if( p > end_ )
|
||||||
throw MalformedBundleException( "packet too short for bundle element" );
|
{
|
||||||
|
state_ = MALFORMED_BUNDLE_TOO_SHORT_FOR_ELEMENT_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
++elementCount_;
|
++elementCount_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( p != end_ )
|
if( p != end_ )
|
||||||
throw MalformedBundleException( "bundle contents " );
|
{
|
||||||
|
state_ = MALFORMED_BUNDLE_CONTENT_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -42,49 +42,11 @@
|
|||||||
#include <cstring> // size_t
|
#include <cstring> // size_t
|
||||||
|
|
||||||
#include "OscTypes.h"
|
#include "OscTypes.h"
|
||||||
#include "OscException.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace osc{
|
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" )
|
|
||||||
: Exception( w ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class MalformedBundleException : public Exception{
|
|
||||||
public:
|
|
||||||
MalformedBundleException( const char *w="malformed bundle" )
|
|
||||||
: Exception( w ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class WrongArgumentTypeException : public Exception{
|
|
||||||
public:
|
|
||||||
WrongArgumentTypeException( const char *w="wrong argument type" )
|
|
||||||
: Exception( w ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class MissingArgumentException : public Exception{
|
|
||||||
public:
|
|
||||||
MissingArgumentException( const char *w="missing argument" )
|
|
||||||
: Exception( w ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ExcessArgumentException : public Exception{
|
|
||||||
public:
|
|
||||||
ExcessArgumentException( const char *w="too many arguments" )
|
|
||||||
: Exception( w ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ReceivedPacket{
|
class ReceivedPacket{
|
||||||
public:
|
public:
|
||||||
// Although the OSC spec is not entirely clear on this, we only support
|
// Although the OSC spec is not entirely clear on this, we only support
|
||||||
@@ -94,16 +56,16 @@ public:
|
|||||||
|
|
||||||
ReceivedPacket( const char *contents, osc_bundle_element_size_t size )
|
ReceivedPacket( const char *contents, osc_bundle_element_size_t size )
|
||||||
: contents_( contents )
|
: contents_( contents )
|
||||||
, size_( ValidateSize(size) ) {}
|
, size_( ValidateSize(size, &state_) ) {}
|
||||||
|
|
||||||
ReceivedPacket( const char *contents, std::size_t size )
|
ReceivedPacket( const char *contents, std::size_t size )
|
||||||
: contents_( contents )
|
: contents_( contents )
|
||||||
, size_( ValidateSize( (osc_bundle_element_size_t)size ) ) {}
|
, size_( ValidateSize( (osc_bundle_element_size_t)size, &state_ ) ) {}
|
||||||
|
|
||||||
#if !(defined(__x86_64__) || defined(_M_X64))
|
#if !(defined(__x86_64__) || defined(_M_X64))
|
||||||
ReceivedPacket( const char *contents, int size )
|
ReceivedPacket( const char *contents, int size )
|
||||||
: contents_( contents )
|
: contents_( contents )
|
||||||
, size_( ValidateSize( (osc_bundle_element_size_t)size ) ) {}
|
, size_( ValidateSize( (osc_bundle_element_size_t)size, &state_ ) ) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool IsMessage() const { return !IsBundle(); }
|
bool IsMessage() const { return !IsBundle(); }
|
||||||
@@ -111,12 +73,14 @@ public:
|
|||||||
|
|
||||||
osc_bundle_element_size_t Size() const { return size_; }
|
osc_bundle_element_size_t Size() const { return size_; }
|
||||||
const char *Contents() const { return contents_; }
|
const char *Contents() const { return contents_; }
|
||||||
|
Errors State() const { return state_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char *contents_;
|
const char *contents_;
|
||||||
osc_bundle_element_size_t size_;
|
osc_bundle_element_size_t size_;
|
||||||
|
Errors state_;
|
||||||
|
|
||||||
static osc_bundle_element_size_t ValidateSize( osc_bundle_element_size_t size )
|
static osc_bundle_element_size_t ValidateSize( osc_bundle_element_size_t size, Errors * state )
|
||||||
{
|
{
|
||||||
// sanity check integer types declared in OscTypes.h
|
// sanity check integer types declared in OscTypes.h
|
||||||
// you'll need to fix OscTypes.h if any of these asserts fail
|
// you'll need to fix OscTypes.h if any of these asserts fail
|
||||||
@@ -126,14 +90,24 @@ private:
|
|||||||
assert( sizeof(osc::uint64) == 8 );
|
assert( sizeof(osc::uint64) == 8 );
|
||||||
|
|
||||||
if( !IsValidElementSizeValue(size) )
|
if( !IsValidElementSizeValue(size) )
|
||||||
throw MalformedPacketException( "invalid packet size" );
|
{
|
||||||
|
*state = MALFORMED_PACKET_INVALID_SIZE_ERROR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if( size == 0 )
|
if( size == 0 )
|
||||||
throw MalformedPacketException( "zero length elements not permitted" );
|
{
|
||||||
|
*state = MALFORMED_PACKET_ZERO_SIZE_ERROR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if( !IsMultipleOf4(size) )
|
if( !IsMultipleOf4(size) )
|
||||||
throw MalformedPacketException( "element size must be multiple of four" );
|
{
|
||||||
|
*state = MALFORMED_PACKET_NOT_MULTIPLE_OF_4_ERROR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*state = SUCCESS;
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -222,61 +196,61 @@ public:
|
|||||||
|
|
||||||
bool IsBool() const
|
bool IsBool() const
|
||||||
{ return *typeTagPtr_ == TRUE_TYPE_TAG || *typeTagPtr_ == FALSE_TYPE_TAG; }
|
{ return *typeTagPtr_ == TRUE_TYPE_TAG || *typeTagPtr_ == FALSE_TYPE_TAG; }
|
||||||
bool AsBool() const;
|
bool AsBool(Errors & state) const;
|
||||||
bool AsBoolUnchecked() const;
|
bool AsBoolUnchecked(Errors & state) const;
|
||||||
|
|
||||||
bool IsNil() const { return *typeTagPtr_ == NIL_TYPE_TAG; }
|
bool IsNil() const { return *typeTagPtr_ == NIL_TYPE_TAG; }
|
||||||
bool IsInfinitum() const { return *typeTagPtr_ == INFINITUM_TYPE_TAG; }
|
bool IsInfinitum() const { return *typeTagPtr_ == INFINITUM_TYPE_TAG; }
|
||||||
|
|
||||||
bool IsInt32() const { return *typeTagPtr_ == INT32_TYPE_TAG; }
|
bool IsInt32() const { return *typeTagPtr_ == INT32_TYPE_TAG; }
|
||||||
int32 AsInt32() const;
|
int32 AsInt32(Errors & state) const;
|
||||||
int32 AsInt32Unchecked() const;
|
int32 AsInt32Unchecked() const;
|
||||||
|
|
||||||
bool IsFloat() const { return *typeTagPtr_ == FLOAT_TYPE_TAG; }
|
bool IsFloat() const { return *typeTagPtr_ == FLOAT_TYPE_TAG; }
|
||||||
float AsFloat() const;
|
float AsFloat(Errors & state) const;
|
||||||
float AsFloatUnchecked() const;
|
float AsFloatUnchecked() const;
|
||||||
|
|
||||||
bool IsChar() const { return *typeTagPtr_ == CHAR_TYPE_TAG; }
|
bool IsChar() const { return *typeTagPtr_ == CHAR_TYPE_TAG; }
|
||||||
char AsChar() const;
|
char AsChar(Errors & state) const;
|
||||||
char AsCharUnchecked() const;
|
char AsCharUnchecked() const;
|
||||||
|
|
||||||
bool IsRgbaColor() const { return *typeTagPtr_ == RGBA_COLOR_TYPE_TAG; }
|
bool IsRgbaColor() const { return *typeTagPtr_ == RGBA_COLOR_TYPE_TAG; }
|
||||||
uint32 AsRgbaColor() const;
|
uint32 AsRgbaColor(Errors & state) const;
|
||||||
uint32 AsRgbaColorUnchecked() const;
|
uint32 AsRgbaColorUnchecked() const;
|
||||||
|
|
||||||
bool IsMidiMessage() const { return *typeTagPtr_ == MIDI_MESSAGE_TYPE_TAG; }
|
bool IsMidiMessage() const { return *typeTagPtr_ == MIDI_MESSAGE_TYPE_TAG; }
|
||||||
uint32 AsMidiMessage() const;
|
uint32 AsMidiMessage(Errors & state) const;
|
||||||
uint32 AsMidiMessageUnchecked() const;
|
uint32 AsMidiMessageUnchecked() const;
|
||||||
|
|
||||||
bool IsInt64() const { return *typeTagPtr_ == INT64_TYPE_TAG; }
|
bool IsInt64() const { return *typeTagPtr_ == INT64_TYPE_TAG; }
|
||||||
int64 AsInt64() const;
|
int64 AsInt64(Errors & state) const;
|
||||||
int64 AsInt64Unchecked() const;
|
int64 AsInt64Unchecked() const;
|
||||||
|
|
||||||
bool IsTimeTag() const { return *typeTagPtr_ == TIME_TAG_TYPE_TAG; }
|
bool IsTimeTag() const { return *typeTagPtr_ == TIME_TAG_TYPE_TAG; }
|
||||||
uint64 AsTimeTag() const;
|
uint64 AsTimeTag(Errors & state) const;
|
||||||
uint64 AsTimeTagUnchecked() const;
|
uint64 AsTimeTagUnchecked() const;
|
||||||
|
|
||||||
bool IsDouble() const { return *typeTagPtr_ == DOUBLE_TYPE_TAG; }
|
bool IsDouble() const { return *typeTagPtr_ == DOUBLE_TYPE_TAG; }
|
||||||
double AsDouble() const;
|
double AsDouble(Errors & state) const;
|
||||||
double AsDoubleUnchecked() const;
|
double AsDoubleUnchecked() const;
|
||||||
|
|
||||||
bool IsString() const { return *typeTagPtr_ == STRING_TYPE_TAG; }
|
bool IsString() const { return *typeTagPtr_ == STRING_TYPE_TAG; }
|
||||||
const char* AsString() const;
|
const char* AsString(Errors & state) const;
|
||||||
const char* AsStringUnchecked() const { return argumentPtr_; }
|
const char* AsStringUnchecked() const { return argumentPtr_; }
|
||||||
|
|
||||||
bool IsSymbol() const { return *typeTagPtr_ == SYMBOL_TYPE_TAG; }
|
bool IsSymbol() const { return *typeTagPtr_ == SYMBOL_TYPE_TAG; }
|
||||||
const char* AsSymbol() const;
|
const char* AsSymbol(Errors & state) const;
|
||||||
const char* AsSymbolUnchecked() const { return argumentPtr_; }
|
const char* AsSymbolUnchecked() const { return argumentPtr_; }
|
||||||
|
|
||||||
bool IsBlob() const { return *typeTagPtr_ == BLOB_TYPE_TAG; }
|
bool IsBlob() const { return *typeTagPtr_ == BLOB_TYPE_TAG; }
|
||||||
void AsBlob( const void*& data, osc_bundle_element_size_t& size ) const;
|
void AsBlob( const void*& data, osc_bundle_element_size_t& size, Errors & state ) const;
|
||||||
void AsBlobUnchecked( const void*& data, osc_bundle_element_size_t& size ) const;
|
void AsBlobUnchecked( const void*& data, osc_bundle_element_size_t& size, Errors & state ) const;
|
||||||
|
|
||||||
bool IsArrayBegin() const { return *typeTagPtr_ == ARRAY_BEGIN_TYPE_TAG; }
|
bool IsArrayBegin() const { return *typeTagPtr_ == ARRAY_BEGIN_TYPE_TAG; }
|
||||||
bool IsArrayEnd() const { return *typeTagPtr_ == ARRAY_END_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.
|
// 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.
|
// Only valid at array start. Will throw an exception if IsArrayStart() == false.
|
||||||
std::size_t ComputeArrayItemCount() const;
|
std::size_t ComputeArrayItemCount(Errors & state) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char *typeTagPtr_;
|
const char *typeTagPtr_;
|
||||||
@@ -338,21 +312,29 @@ class ReceivedMessageArgumentStream{
|
|||||||
ReceivedMessageArgumentStream( const ReceivedMessageArgumentIterator& begin,
|
ReceivedMessageArgumentStream( const ReceivedMessageArgumentIterator& begin,
|
||||||
const ReceivedMessageArgumentIterator& end )
|
const ReceivedMessageArgumentIterator& end )
|
||||||
: p_( begin )
|
: p_( begin )
|
||||||
, end_( end ) {}
|
, end_( end )
|
||||||
|
, state_( SUCCESS ) {}
|
||||||
|
|
||||||
ReceivedMessageArgumentIterator p_, end_;
|
ReceivedMessageArgumentIterator p_, end_;
|
||||||
|
Errors state_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
Errors State() const { return state_; }
|
||||||
|
|
||||||
// end of stream
|
// end of stream
|
||||||
bool Eos() const { return p_ == end_; }
|
bool Eos() const { return p_ == end_; }
|
||||||
|
|
||||||
ReceivedMessageArgumentStream& operator>>( bool& rhs )
|
ReceivedMessageArgumentStream& operator>>( bool& rhs )
|
||||||
{
|
{
|
||||||
if( Eos() )
|
if( Eos() )
|
||||||
throw MissingArgumentException();
|
{
|
||||||
|
state_ = MISSING_ARGUMENT_ERROR;
|
||||||
rhs = (*p_++).AsBool();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rhs = (*p_++).AsBool(state_);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,99 +345,143 @@ public:
|
|||||||
ReceivedMessageArgumentStream& operator>>( int32& rhs )
|
ReceivedMessageArgumentStream& operator>>( int32& rhs )
|
||||||
{
|
{
|
||||||
if( Eos() )
|
if( Eos() )
|
||||||
throw MissingArgumentException();
|
{
|
||||||
|
state_ = MISSING_ARGUMENT_ERROR;
|
||||||
rhs = (*p_++).AsInt32();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rhs = (*p_++).AsInt32(state_);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceivedMessageArgumentStream& operator>>( float& rhs )
|
ReceivedMessageArgumentStream& operator>>( float& rhs )
|
||||||
{
|
{
|
||||||
if( Eos() )
|
if( Eos() )
|
||||||
throw MissingArgumentException();
|
{
|
||||||
|
state_ = MISSING_ARGUMENT_ERROR;
|
||||||
rhs = (*p_++).AsFloat();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rhs = (*p_++).AsFloat(state_);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceivedMessageArgumentStream& operator>>( char& rhs )
|
ReceivedMessageArgumentStream& operator>>( char& rhs )
|
||||||
{
|
{
|
||||||
if( Eos() )
|
if( Eos() )
|
||||||
throw MissingArgumentException();
|
{
|
||||||
|
state_ = MISSING_ARGUMENT_ERROR;
|
||||||
rhs = (*p_++).AsChar();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rhs = (*p_++).AsChar(state_);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceivedMessageArgumentStream& operator>>( RgbaColor& rhs )
|
ReceivedMessageArgumentStream& operator>>( RgbaColor& rhs )
|
||||||
{
|
{
|
||||||
if( Eos() )
|
if( Eos() )
|
||||||
throw MissingArgumentException();
|
{
|
||||||
|
state_ = MISSING_ARGUMENT_ERROR;
|
||||||
rhs.value = (*p_++).AsRgbaColor();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rhs.value = (*p_++).AsRgbaColor(state_);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceivedMessageArgumentStream& operator>>( MidiMessage& rhs )
|
ReceivedMessageArgumentStream& operator>>( MidiMessage& rhs )
|
||||||
{
|
{
|
||||||
if( Eos() )
|
if( Eos() )
|
||||||
throw MissingArgumentException();
|
{
|
||||||
|
state_ = MISSING_ARGUMENT_ERROR;
|
||||||
rhs.value = (*p_++).AsMidiMessage();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rhs.value = (*p_++).AsMidiMessage(state_);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceivedMessageArgumentStream& operator>>( int64& rhs )
|
ReceivedMessageArgumentStream& operator>>( int64& rhs )
|
||||||
{
|
{
|
||||||
if( Eos() )
|
if( Eos() )
|
||||||
throw MissingArgumentException();
|
{
|
||||||
|
state_ = MISSING_ARGUMENT_ERROR;
|
||||||
rhs = (*p_++).AsInt64();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rhs = (*p_++).AsInt64(state_);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceivedMessageArgumentStream& operator>>( TimeTag& rhs )
|
ReceivedMessageArgumentStream& operator>>( TimeTag& rhs )
|
||||||
{
|
{
|
||||||
if( Eos() )
|
if( Eos() )
|
||||||
throw MissingArgumentException();
|
{
|
||||||
|
state_ = MISSING_ARGUMENT_ERROR;
|
||||||
rhs.value = (*p_++).AsTimeTag();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rhs.value = (*p_++).AsTimeTag(state_);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceivedMessageArgumentStream& operator>>( double& rhs )
|
ReceivedMessageArgumentStream& operator>>( double& rhs )
|
||||||
{
|
{
|
||||||
if( Eos() )
|
if( Eos() )
|
||||||
throw MissingArgumentException();
|
{
|
||||||
|
state_ = MISSING_ARGUMENT_ERROR;
|
||||||
rhs = (*p_++).AsDouble();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rhs = (*p_++).AsDouble(state_);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceivedMessageArgumentStream& operator>>( Blob& rhs )
|
ReceivedMessageArgumentStream& operator>>( Blob& rhs )
|
||||||
{
|
{
|
||||||
if( Eos() )
|
if( Eos() )
|
||||||
throw MissingArgumentException();
|
{
|
||||||
|
state_ = MISSING_ARGUMENT_ERROR;
|
||||||
(*p_++).AsBlob( rhs.data, rhs.size );
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*p_++).AsBlob( rhs.data, rhs.size, state_ );
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceivedMessageArgumentStream& operator>>( const char*& rhs )
|
ReceivedMessageArgumentStream& operator>>( const char*& rhs )
|
||||||
{
|
{
|
||||||
if( Eos() )
|
if( Eos() )
|
||||||
throw MissingArgumentException();
|
{
|
||||||
|
state_ = MISSING_ARGUMENT_ERROR;
|
||||||
rhs = (*p_++).AsString();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rhs = (*p_++).AsString(state_);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceivedMessageArgumentStream& operator>>( Symbol& rhs )
|
ReceivedMessageArgumentStream& operator>>( Symbol& rhs )
|
||||||
{
|
{
|
||||||
if( Eos() )
|
if( Eos() )
|
||||||
throw MissingArgumentException();
|
{
|
||||||
|
state_ = MISSING_ARGUMENT_ERROR;
|
||||||
rhs.value = (*p_++).AsSymbol();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rhs.value = (*p_++).AsSymbol(state_);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,9 +489,10 @@ public:
|
|||||||
{
|
{
|
||||||
(void) rhs; // suppress unused parameter warning
|
(void) rhs; // suppress unused parameter warning
|
||||||
|
|
||||||
if( !Eos() )
|
if( Eos() )
|
||||||
throw ExcessArgumentException();
|
{
|
||||||
|
state_ = EXCESS_ARGUMENT_ERROR;
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -477,6 +504,8 @@ public:
|
|||||||
explicit ReceivedMessage( const ReceivedPacket& packet );
|
explicit ReceivedMessage( const ReceivedPacket& packet );
|
||||||
explicit ReceivedMessage( const ReceivedBundleElement& bundleElement );
|
explicit ReceivedMessage( const ReceivedBundleElement& bundleElement );
|
||||||
|
|
||||||
|
Errors State() const { return state_; }
|
||||||
|
|
||||||
const char *AddressPattern() const { return addressPattern_; }
|
const char *AddressPattern() const { return addressPattern_; }
|
||||||
|
|
||||||
// Support for non-standard SuperCollider integer address patterns:
|
// Support for non-standard SuperCollider integer address patterns:
|
||||||
@@ -510,6 +539,7 @@ private:
|
|||||||
const char *typeTagsBegin_;
|
const char *typeTagsBegin_;
|
||||||
const char *typeTagsEnd_;
|
const char *typeTagsEnd_;
|
||||||
const char *arguments_;
|
const char *arguments_;
|
||||||
|
Errors state_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -519,6 +549,8 @@ public:
|
|||||||
explicit ReceivedBundle( const ReceivedPacket& packet );
|
explicit ReceivedBundle( const ReceivedPacket& packet );
|
||||||
explicit ReceivedBundle( const ReceivedBundleElement& bundleElement );
|
explicit ReceivedBundle( const ReceivedBundleElement& bundleElement );
|
||||||
|
|
||||||
|
Errors State() const { return state_; }
|
||||||
|
|
||||||
uint64 TimeTag() const;
|
uint64 TimeTag() const;
|
||||||
|
|
||||||
uint32 ElementCount() const { return elementCount_; }
|
uint32 ElementCount() const { return elementCount_; }
|
||||||
@@ -539,6 +571,7 @@ private:
|
|||||||
const char *timeTag_;
|
const char *timeTag_;
|
||||||
const char *end_;
|
const char *end_;
|
||||||
uint32 elementCount_;
|
uint32 elementCount_;
|
||||||
|
Errors state_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -52,4 +52,52 @@ InfinitumType Infinitum;
|
|||||||
ArrayInitiator BeginArray;
|
ArrayInitiator BeginArray;
|
||||||
ArrayTerminator EndArray;
|
ArrayTerminator EndArray;
|
||||||
|
|
||||||
|
const TCHAR * errorString(Errors value)
|
||||||
|
{
|
||||||
|
static const TCHAR * ERROR_STR[] = {
|
||||||
|
TEXT("No Error"),
|
||||||
|
|
||||||
|
TEXT("Malformed packet"),
|
||||||
|
TEXT("Malformed packet: invalid size"),
|
||||||
|
TEXT("Malformed packet: zero size"),
|
||||||
|
TEXT("Malformed packet: not multiple of 4"),
|
||||||
|
|
||||||
|
TEXT("Malformed message"),
|
||||||
|
TEXT("Malformed message: invalid size"),
|
||||||
|
TEXT("Malformed message: zero size"),
|
||||||
|
TEXT("Malformed message: not multiple of 4"),
|
||||||
|
TEXT("Malformed message: invalid blob size"),
|
||||||
|
TEXT("Malformed message: unterminated address pattern"),
|
||||||
|
TEXT("Malformed message: unterminated string"),
|
||||||
|
TEXT("Malformed message: unterminated array"),
|
||||||
|
TEXT("Malformed message: no type tags"),
|
||||||
|
TEXT("Malformed message: unterminated type tags"),
|
||||||
|
TEXT("Malformed message: argument exceed msg size"),
|
||||||
|
TEXT("Malformed message: unknown type tag"),
|
||||||
|
|
||||||
|
TEXT("Malformed bundle"),
|
||||||
|
TEXT("Malformed bundle: invalid size"),
|
||||||
|
TEXT("Malformed bundle: invalid address pattern"),
|
||||||
|
TEXT("Malformed bundle: too short"),
|
||||||
|
TEXT("Malformed bundle: too short for element size"),
|
||||||
|
TEXT("Malformed bundle: too short for element"),
|
||||||
|
TEXT("Malformed bundle: not multiple of 4"),
|
||||||
|
TEXT("Malformed bundle: element not multiple of 4"),
|
||||||
|
TEXT("Malformed bundle: content"),
|
||||||
|
|
||||||
|
TEXT("Wrong argument type"),
|
||||||
|
TEXT("Missing argument"),
|
||||||
|
TEXT("Excess argument"),
|
||||||
|
TEXT("Out of buffer memory"),
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert((sizeof(ERROR_STR) / sizeof(*ERROR_STR) == ERRORS_COUNT), "Error messages mismatch");
|
||||||
|
if(value < 0 || value >= ERRORS_COUNT)
|
||||||
|
{
|
||||||
|
check(false);
|
||||||
|
return TEXT("Unknown error code");
|
||||||
|
}
|
||||||
|
return ERROR_STR[value];
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace osc
|
} // namespace osc
|
||||||
|
|||||||
@@ -234,6 +234,48 @@ struct ArrayTerminator{
|
|||||||
|
|
||||||
extern ArrayTerminator EndArray;
|
extern ArrayTerminator EndArray;
|
||||||
|
|
||||||
|
|
||||||
|
enum Errors {
|
||||||
|
SUCCESS = 0,
|
||||||
|
|
||||||
|
MALFORMED_PACKET_ERROR,
|
||||||
|
MALFORMED_PACKET_INVALID_SIZE_ERROR,
|
||||||
|
MALFORMED_PACKET_ZERO_SIZE_ERROR,
|
||||||
|
MALFORMED_PACKET_NOT_MULTIPLE_OF_4_ERROR,
|
||||||
|
|
||||||
|
MALFORMED_MESSAGE_ERROR,
|
||||||
|
MALFORMED_MESSAGE_INVALID_SIZE_ERROR,
|
||||||
|
MALFORMED_MESSAGE_ZERO_SIZE_ERROR,
|
||||||
|
MALFORMED_MESSAGE_NOT_MULTIPLE_OF_4_ERROR,
|
||||||
|
MALFORMED_MESSAGE_INVALID_BLOB_SIZE_ERROR,
|
||||||
|
MALFORMED_MESSAGE_UNTERMINATED_ADDRESS_PATTERN_ERROR,
|
||||||
|
MALFORMED_MESSAGE_UNTERMINATED_STRING_ERROR,
|
||||||
|
MALFORMED_MESSAGE_UNTERMINATED_ARRAY_ERROR,
|
||||||
|
MALFORMED_MESSAGE_NO_TYPE_TAGS_ERROR,
|
||||||
|
MALFORMED_MESSAGE_UNTERMINATED_TYPE_TAGS_ERROR,
|
||||||
|
MALFORMED_MESSAGE_ARGUMENT_EXCEED_MSG_SIZE_ERROR,
|
||||||
|
MALFORMED_MESSAGE_UNKNOWN_TYPE_TAG_ERROR,
|
||||||
|
|
||||||
|
MALFORMED_BUNDLE_ERROR,
|
||||||
|
MALFORMED_BUNDLE_INVALID_SIZE_ERROR,
|
||||||
|
MALFORMED_BUNDLE_INVALID_ADDRESS_PATTERN_ERROR,
|
||||||
|
MALFORMED_BUNDLE_TOO_SHORT_ERROR,
|
||||||
|
MALFORMED_BUNDLE_TOO_SHORT_FOR_ELEMENT_SIZE_ERROR,
|
||||||
|
MALFORMED_BUNDLE_TOO_SHORT_FOR_ELEMENT_ERROR,
|
||||||
|
MALFORMED_BUNDLE_NOT_MULTIPLE_OF_4_ERROR,
|
||||||
|
MALFORMED_BUNDLE_ELEMENT_NOT_MULTIPLE_OF_4_ERROR,
|
||||||
|
MALFORMED_BUNDLE_CONTENT_ERROR,
|
||||||
|
|
||||||
|
WRONG_ARGUMENT_TYPE_ERROR,
|
||||||
|
MISSING_ARGUMENT_ERROR,
|
||||||
|
EXCESS_ARGUMENT_ERROR,
|
||||||
|
OUT_OF_BUFFER_MEMORY_ERROR,
|
||||||
|
|
||||||
|
ERRORS_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
|
const TCHAR * errorString(Errors value);
|
||||||
|
|
||||||
} // namespace osc
|
} // namespace osc
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,11 @@ void UOscDispatcher::UnregisterReceiver(IOscReceiverInterface * receiver)
|
|||||||
|
|
||||||
static void SendMessage(TCircularQueue<std::pair<FName, TArray<FOscDataElemStruct>>> & _pendingMessages, const osc::ReceivedMessage & message)
|
static void SendMessage(TCircularQueue<std::pair<FName, TArray<FOscDataElemStruct>>> & _pendingMessages, const osc::ReceivedMessage & message)
|
||||||
{
|
{
|
||||||
|
if(message.State() != osc::SUCCESS)
|
||||||
|
{
|
||||||
|
UE_LOG(LogOSC, Warning, TEXT("OSC Received Message Error: %s"), osc::errorString(message.State()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
const FName address(message.AddressPattern());
|
const FName address(message.AddressPattern());
|
||||||
|
|
||||||
TArray<FOscDataElemStruct> data;
|
TArray<FOscDataElemStruct> data;
|
||||||
@@ -114,7 +119,9 @@ static void SendMessage(TCircularQueue<std::pair<FName, TArray<FOscDataElemStruc
|
|||||||
}
|
}
|
||||||
else if(it->IsBool())
|
else if(it->IsBool())
|
||||||
{
|
{
|
||||||
elem.SetBool(it->AsBoolUnchecked());
|
osc::Errors error = osc::SUCCESS;
|
||||||
|
elem.SetBool(it->AsBoolUnchecked(error));
|
||||||
|
check(error == osc::SUCCESS);
|
||||||
}
|
}
|
||||||
else if(it->IsString())
|
else if(it->IsString())
|
||||||
{
|
{
|
||||||
@@ -135,6 +142,12 @@ static void SendMessage(TCircularQueue<std::pair<FName, TArray<FOscDataElemStruc
|
|||||||
|
|
||||||
static void SendBundle(TCircularQueue<std::pair<FName, TArray<FOscDataElemStruct>>> & _pendingMessages, const osc::ReceivedBundle & bundle)
|
static void SendBundle(TCircularQueue<std::pair<FName, TArray<FOscDataElemStruct>>> & _pendingMessages, const osc::ReceivedBundle & bundle)
|
||||||
{
|
{
|
||||||
|
if(bundle.State() != osc::SUCCESS)
|
||||||
|
{
|
||||||
|
UE_LOG(LogOSC, Warning, TEXT("OSC Received Bundle Error: %s"), osc::errorString(bundle.State()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto begin = bundle.ElementsBegin();
|
const auto begin = bundle.ElementsBegin();
|
||||||
const auto end = bundle.ElementsEnd();
|
const auto end = bundle.ElementsEnd();
|
||||||
for(auto it = begin; it != end; ++it)
|
for(auto it = begin; it != end; ++it)
|
||||||
@@ -153,26 +166,23 @@ static void SendBundle(TCircularQueue<std::pair<FName, TArray<FOscDataElemStruct
|
|||||||
void UOscDispatcher::Callback(const FArrayReaderPtr& data, const FIPv4Endpoint&)
|
void UOscDispatcher::Callback(const FArrayReaderPtr& data, const FIPv4Endpoint&)
|
||||||
{
|
{
|
||||||
const auto wasEmpty = _pendingMessages.IsEmpty();
|
const auto wasEmpty = _pendingMessages.IsEmpty();
|
||||||
try
|
|
||||||
|
const osc::ReceivedPacket packet((const char *)data->GetData(), data->Num());
|
||||||
|
if(packet.State() != osc::SUCCESS)
|
||||||
{
|
{
|
||||||
const osc::ReceivedPacket packet((const char *)data->GetData(), data->Num());
|
UE_LOG(LogOSC, Warning, TEXT("OSC Received Packet Error: %s"), osc::errorString(packet.State()));
|
||||||
if(packet.IsBundle())
|
return;
|
||||||
{
|
|
||||||
SendBundle(_pendingMessages, osc::ReceivedBundle(packet));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SendMessage(_pendingMessages, osc::ReceivedMessage(packet));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch(osc::Exception &e)
|
|
||||||
|
if(packet.IsBundle())
|
||||||
{
|
{
|
||||||
// Exceptions are disabled by default, so destructors are not called.
|
SendBundle(_pendingMessages, osc::ReceivedBundle(packet));
|
||||||
// We don't care: there is no acquired resource to release.
|
|
||||||
const FString wide(e.what());
|
|
||||||
UE_LOG(LogOSC, Warning, TEXT("OSC Message Error: %s"), *wide);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendMessage(_pendingMessages, osc::ReceivedMessage(packet));
|
||||||
|
}
|
||||||
|
|
||||||
// Set a single callback in the main thread per frame.
|
// Set a single callback in the main thread per frame.
|
||||||
if(wasEmpty && !_pendingMessages.IsEmpty())
|
if(wasEmpty && !_pendingMessages.IsEmpty())
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user