-/*\r
- oscpack -- Open Sound Control packet manipulation library\r
- http://www.audiomulch.com/~rossb/oscpack\r
-\r
- Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>\r
-\r
- Permission is hereby granted, free of charge, to any person obtaining\r
- a copy of this software and associated documentation files\r
- (the "Software"), to deal in the Software without restriction,\r
- including without limitation the rights to use, copy, modify, merge,\r
- publish, distribute, sublicense, and/or sell copies of the Software,\r
- and to permit persons to whom the Software is furnished to do so,\r
- subject to the following conditions:\r
-\r
- The above copyright notice and this permission notice shall be\r
- included in all copies or substantial portions of the Software.\r
-\r
- Any person wishing to distribute modifications to the Software is\r
- requested to send the modifications to the original developer so that\r
- they can be incorporated into the canonical version.\r
-\r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
- ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
- CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
-*/\r
-#ifndef INCLUDED_OSCRECEIVEDELEMENTS_H\r
-#define INCLUDED_OSCRECEIVEDELEMENTS_H\r
-\r
-#include <cstddef>\r
-\r
-#include "OscTypes.h"\r
-#include "OscException.h"\r
-\r
-\r
-namespace osc{\r
-\r
-\r
-class MalformedMessageException : public Exception{\r
-public:\r
- MalformedMessageException( const char *w="malformed message" )\r
- : Exception( w ) {}\r
-};\r
-\r
-class MalformedBundleException : public Exception{\r
-public:\r
- MalformedBundleException( const char *w="malformed bundle" )\r
- : Exception( w ) {}\r
-};\r
-\r
-class WrongArgumentTypeException : public Exception{\r
-public:\r
- WrongArgumentTypeException( const char *w="wrong argument type" )\r
- : Exception( w ) {}\r
-};\r
-\r
-class MissingArgumentException : public Exception{\r
-public:\r
- MissingArgumentException( const char *w="missing argument" )\r
- : Exception( w ) {}\r
-};\r
-\r
-class ExcessArgumentException : public Exception{\r
-public:\r
- ExcessArgumentException( const char *w="too many arguments" )\r
- : Exception( w ) {}\r
-};\r
-\r
-\r
-class ReceivedPacket{\r
-public:\r
- ReceivedPacket( const char *contents, int32 size )\r
- : contents_( contents )\r
- , size_( size ) {}\r
-\r
- bool IsMessage() const { return !IsBundle(); }\r
- bool IsBundle() const;\r
-\r
- int32 Size() const { return size_; }\r
- const char *Contents() const { return contents_; }\r
-\r
-private:\r
- const char *contents_;\r
- int32 size_;\r
-};\r
-\r
-\r
-class ReceivedBundleElement{\r
-public:\r
- ReceivedBundleElement( const char *size )\r
- : size_( size ) {}\r
-\r
- friend class ReceivedBundleElementIterator;\r
-\r
- bool IsMessage() const { return !IsBundle(); }\r
- bool IsBundle() const;\r
-\r
- int32 Size() const;\r
- const char *Contents() const { return size_ + 4; }\r
-\r
-private:\r
- const char *size_;\r
-};\r
-\r
-\r
-class ReceivedBundleElementIterator{\r
-public:\r
- ReceivedBundleElementIterator( const char *sizePtr )\r
- : value_( sizePtr ) {}\r
-\r
- ReceivedBundleElementIterator operator++()\r
- {\r
- Advance();\r
- return *this;\r
- }\r
-\r
- ReceivedBundleElementIterator operator++(int)\r
- {\r
- ReceivedBundleElementIterator old( *this );\r
- Advance();\r
- return old;\r
- }\r
-\r
- const ReceivedBundleElement& operator*() const { return value_; }\r
-\r
- const ReceivedBundleElement* operator->() const { return &value_; }\r
-\r
- friend bool operator==(const ReceivedBundleElementIterator& lhs,\r
- const ReceivedBundleElementIterator& rhs );\r
-\r
-private:\r
- ReceivedBundleElement value_;\r
-\r
- void Advance() { value_.size_ = value_.Contents() + value_.Size(); }\r
-\r
- bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const\r
- {\r
- return value_.size_ == rhs.value_.size_;\r
- }\r
-};\r
-\r
-inline bool operator==(const ReceivedBundleElementIterator& lhs,\r
- const ReceivedBundleElementIterator& rhs )\r
-{ \r
- return lhs.IsEqualTo( rhs );\r
-}\r
-\r
-inline bool operator!=(const ReceivedBundleElementIterator& lhs,\r
- const ReceivedBundleElementIterator& rhs )\r
-{\r
- return !( lhs == rhs );\r
-}\r
-\r
-\r
-class ReceivedMessageArgument{\r
-public:\r
- ReceivedMessageArgument( const char *typeTag, const char *argument )\r
- : typeTag_( typeTag )\r
- , argument_( argument ) {}\r
-\r
- friend class ReceivedMessageArgumentIterator;\r
- \r
- const char TypeTag() const { return *typeTag_; }\r
-\r
- // the unchecked methods below don't check whether the argument actually\r
- // is of the specified type. they should only be used if you've already\r
- // checked the type tag or the associated IsType() method.\r
-\r
- bool IsBool() const\r
- { return *typeTag_ == TRUE_TYPE_TAG || *typeTag_ == FALSE_TYPE_TAG; }\r
- bool AsBool() const;\r
- bool AsBoolUnchecked() const;\r
-\r
- bool IsNil() const { return *typeTag_ == NIL_TYPE_TAG; }\r
- bool IsInfinitum() const { return *typeTag_ == INFINITUM_TYPE_TAG; }\r
-\r
- bool IsInt32() const { return *typeTag_ == INT32_TYPE_TAG; }\r
- int32 AsInt32() const;\r
- int32 AsInt32Unchecked() const;\r
-\r
- bool IsFloat() const { return *typeTag_ == FLOAT_TYPE_TAG; }\r
- float AsFloat() const;\r
- float AsFloatUnchecked() const;\r
-\r
- bool IsChar() const { return *typeTag_ == CHAR_TYPE_TAG; }\r
- char AsChar() const;\r
- char AsCharUnchecked() const;\r
-\r
- bool IsRgbaColor() const { return *typeTag_ == RGBA_COLOR_TYPE_TAG; }\r
- uint32 AsRgbaColor() const;\r
- uint32 AsRgbaColorUnchecked() const;\r
-\r
- bool IsMidiMessage() const { return *typeTag_ == MIDI_MESSAGE_TYPE_TAG; }\r
- uint32 AsMidiMessage() const;\r
- uint32 AsMidiMessageUnchecked() const;\r
-\r
- bool IsInt64() const { return *typeTag_ == INT64_TYPE_TAG; }\r
- int64 AsInt64() const;\r
- int64 AsInt64Unchecked() const;\r
-\r
- bool IsTimeTag() const { return *typeTag_ == TIME_TAG_TYPE_TAG; }\r
- uint64 AsTimeTag() const;\r
- uint64 AsTimeTagUnchecked() const;\r
-\r
- bool IsDouble() const { return *typeTag_ == DOUBLE_TYPE_TAG; }\r
- double AsDouble() const;\r
- double AsDoubleUnchecked() const;\r
-\r
- bool IsString() const { return *typeTag_ == STRING_TYPE_TAG; }\r
- const char* AsString() const;\r
- const char* AsStringUnchecked() const { return argument_; }\r
-\r
- bool IsSymbol() const { return *typeTag_ == SYMBOL_TYPE_TAG; }\r
- const char* AsSymbol() const;\r
- const char* AsSymbolUnchecked() const { return argument_; }\r
-\r
- bool IsBlob() const { return *typeTag_ == BLOB_TYPE_TAG; }\r
- void AsBlob( const void*& data, unsigned long& size ) const;\r
- void AsBlobUnchecked( const void*& data, unsigned long& size ) const;\r
- \r
-private:\r
- const char *typeTag_;\r
- const char *argument_;\r
-};\r
-\r
-\r
-class ReceivedMessageArgumentIterator{\r
-public:\r
- ReceivedMessageArgumentIterator( const char *typeTags, const char *arguments )\r
- : value_( typeTags, arguments ) {}\r
-\r
- ReceivedMessageArgumentIterator operator++()\r
- {\r
- Advance();\r
- return *this;\r
- }\r
-\r
- ReceivedMessageArgumentIterator operator++(int)\r
- {\r
- ReceivedMessageArgumentIterator old( *this );\r
- Advance();\r
- return old;\r
- }\r
-\r
- const ReceivedMessageArgument& operator*() const { return value_; }\r
-\r
- const ReceivedMessageArgument* operator->() const { return &value_; }\r
-\r
- friend bool operator==(const ReceivedMessageArgumentIterator& lhs,\r
- const ReceivedMessageArgumentIterator& rhs );\r
-\r
-private:\r
- ReceivedMessageArgument value_;\r
-\r
- void Advance();\r
-\r
- bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const\r
- {\r
- return value_.typeTag_ == rhs.value_.typeTag_;\r
- }\r
-};\r
-\r
-inline bool operator==(const ReceivedMessageArgumentIterator& lhs,\r
- const ReceivedMessageArgumentIterator& rhs )\r
-{ \r
- return lhs.IsEqualTo( rhs );\r
-}\r
-\r
-inline bool operator!=(const ReceivedMessageArgumentIterator& lhs,\r
- const ReceivedMessageArgumentIterator& rhs )\r
-{ \r
- return !( lhs == rhs );\r
-}\r
-\r
-\r
-class ReceivedMessageArgumentStream{\r
- friend class ReceivedMessage;\r
- ReceivedMessageArgumentStream( const ReceivedMessageArgumentIterator& begin,\r
- const ReceivedMessageArgumentIterator& end )\r
- : p_( begin )\r
- , end_( end ) {}\r
-\r
- ReceivedMessageArgumentIterator p_, end_;\r
- \r
-public:\r
-\r
- // end of stream\r
- bool Eos() const { return p_ == end_; }\r
-\r
- ReceivedMessageArgumentStream& operator>>( bool& rhs )\r
- {\r
- if( Eos() )\r
- throw MissingArgumentException();\r
-\r
- rhs = (*p_++).AsBool();\r
- return *this;\r
- }\r
-\r
- // not sure if it would be useful to stream Nil and Infinitum\r
- // for now it's not possible\r
-\r
- ReceivedMessageArgumentStream& operator>>( int32& rhs )\r
- {\r
- if( Eos() )\r
- throw MissingArgumentException();\r
-\r
- rhs = (*p_++).AsInt32();\r
- return *this;\r
- } \r
-\r
- ReceivedMessageArgumentStream& operator>>( float& rhs )\r
- {\r
- if( Eos() )\r
- throw MissingArgumentException();\r
-\r
- rhs = (*p_++).AsFloat();\r
- return *this;\r
- }\r
-\r
- ReceivedMessageArgumentStream& operator>>( char& rhs )\r
- {\r
- if( Eos() )\r
- throw MissingArgumentException();\r
-\r
- rhs = (*p_++).AsChar();\r
- return *this;\r
- }\r
-\r
- ReceivedMessageArgumentStream& operator>>( RgbaColor& rhs )\r
- {\r
- if( Eos() )\r
- throw MissingArgumentException();\r
-\r
- rhs.value = (*p_++).AsRgbaColor();\r
- return *this;\r
- }\r
-\r
- ReceivedMessageArgumentStream& operator>>( MidiMessage& rhs )\r
- {\r
- if( Eos() )\r
- throw MissingArgumentException();\r
-\r
- rhs.value = (*p_++).AsMidiMessage();\r
- return *this;\r
- }\r
-\r
- ReceivedMessageArgumentStream& operator>>( int64& rhs )\r
- {\r
- if( Eos() )\r
- throw MissingArgumentException();\r
-\r
- rhs = (*p_++).AsInt64();\r
- return *this;\r
- }\r
- \r
- ReceivedMessageArgumentStream& operator>>( TimeTag& rhs )\r
- {\r
- if( Eos() )\r
- throw MissingArgumentException();\r
-\r
- rhs.value = (*p_++).AsTimeTag();\r
- return *this;\r
- }\r
-\r
- ReceivedMessageArgumentStream& operator>>( double& rhs )\r
- {\r
- if( Eos() )\r
- throw MissingArgumentException();\r
-\r
- rhs = (*p_++).AsDouble();\r
- return *this;\r
- }\r
-\r
- ReceivedMessageArgumentStream& operator>>( Blob& rhs )\r
- {\r
- if( Eos() )\r
- throw MissingArgumentException();\r
-\r
- (*p_++).AsBlob( rhs.data, rhs.size );\r
- return *this;\r
- }\r
- \r
- ReceivedMessageArgumentStream& operator>>( const char*& rhs )\r
- {\r
- if( Eos() )\r
- throw MissingArgumentException();\r
-\r
- rhs = (*p_++).AsString();\r
- return *this;\r
- }\r
- \r
- ReceivedMessageArgumentStream& operator>>( Symbol& rhs )\r
- {\r
- if( Eos() )\r
- throw MissingArgumentException();\r
-\r
- rhs.value = (*p_++).AsSymbol();\r
- return *this;\r
- }\r
-\r
- ReceivedMessageArgumentStream& operator>>( MessageTerminator& rhs )\r
- {\r
- if( !Eos() )\r
- throw ExcessArgumentException();\r
-\r
- return *this;\r
- }\r
-};\r
-\r
-\r
-class ReceivedMessage{\r
- void Init( const char *bundle, unsigned long size );\r
-public:\r
- explicit ReceivedMessage( const ReceivedPacket& packet );\r
- explicit ReceivedMessage( const ReceivedBundleElement& bundleElement );\r
-\r
- const char *AddressPattern() const { return addressPattern_; }\r
-\r
- // Support for non-standad SuperCollider integer address patterns:\r
- bool AddressPatternIsUInt32() const;\r
- uint32 AddressPatternAsUInt32() const;\r
-\r
- unsigned long ArgumentCount() const { return static_cast<unsigned long>(typeTagsEnd_ - typeTagsBegin_); }\r
-\r
- const char *TypeTags() const { return typeTagsBegin_; }\r
-\r
-\r
- typedef ReceivedMessageArgumentIterator const_iterator;\r
- \r
- ReceivedMessageArgumentIterator ArgumentsBegin() const\r
- {\r
- return ReceivedMessageArgumentIterator( typeTagsBegin_, arguments_ );\r
- }\r
- \r
- ReceivedMessageArgumentIterator ArgumentsEnd() const\r
- {\r
- return ReceivedMessageArgumentIterator( typeTagsEnd_, 0 );\r
- }\r
-\r
- ReceivedMessageArgumentStream ArgumentStream() const\r
- {\r
- return ReceivedMessageArgumentStream( ArgumentsBegin(), ArgumentsEnd() );\r
- }\r
-\r
-private:\r
- const char *addressPattern_;\r
- const char *typeTagsBegin_;\r
- const char *typeTagsEnd_;\r
- const char *arguments_;\r
-};\r
-\r
-\r
-class ReceivedBundle{\r
- void Init( const char *message, unsigned long size );\r
-public:\r
- explicit ReceivedBundle( const ReceivedPacket& packet );\r
- explicit ReceivedBundle( const ReceivedBundleElement& bundleElement );\r
-\r
- uint64 TimeTag() const;\r
-\r
- unsigned long ElementCount() const { return elementCount_; }\r
-\r
- typedef ReceivedBundleElementIterator const_iterator;\r
- \r
- ReceivedBundleElementIterator ElementsBegin() const\r
- {\r
- return ReceivedBundleElementIterator( timeTag_ + 8 );\r
- }\r
- \r
- ReceivedBundleElementIterator ElementsEnd() const\r
- {\r
- return ReceivedBundleElementIterator( end_ );\r
- }\r
-\r
-private:\r
- const char *timeTag_;\r
- const char *end_;\r
- unsigned long elementCount_;\r
-};\r
-\r
-\r
-} // namespace osc\r
-\r
-\r
-#endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */\r
+/*
+ oscpack -- Open Sound Control packet manipulation library
+ http://www.audiomulch.com/~rossb/oscpack
+
+ Copyright (c) 2004-2005 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.
+
+ 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.
+ 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.
+*/
+#ifndef INCLUDED_OSCRECEIVEDELEMENTS_H
+#define INCLUDED_OSCRECEIVEDELEMENTS_H
+
+#include <cstddef>
+
+#include "OscTypes.h"
+#include "OscException.h"
+
+
+namespace osc{
+
+
+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{
+public:
+ ReceivedPacket( const char *contents, int32 size )
+ : contents_( contents )
+ , size_( size ) {}
+
+ bool IsMessage() const { return !IsBundle(); }
+ bool IsBundle() const;
+
+ int32 Size() const { return size_; }
+ const char *Contents() const { return contents_; }
+
+private:
+ const char *contents_;
+ int32 size_;
+};
+
+
+class ReceivedBundleElement{
+public:
+ ReceivedBundleElement( const char *size )
+ : size_( size ) {}
+
+ friend class ReceivedBundleElementIterator;
+
+ bool IsMessage() const { return !IsBundle(); }
+ bool IsBundle() const;
+
+ int32 Size() const;
+ const char *Contents() const { return size_ + 4; }
+
+private:
+ const char *size_;
+};
+
+
+class ReceivedBundleElementIterator{
+public:
+ ReceivedBundleElementIterator( const char *sizePtr )
+ : value_( sizePtr ) {}
+
+ ReceivedBundleElementIterator operator++()
+ {
+ Advance();
+ return *this;
+ }
+
+ ReceivedBundleElementIterator operator++(int)
+ {
+ ReceivedBundleElementIterator old( *this );
+ Advance();
+ return old;
+ }
+
+ const ReceivedBundleElement& operator*() const { return value_; }
+
+ const ReceivedBundleElement* operator->() const { return &value_; }
+
+ friend bool operator==(const ReceivedBundleElementIterator& lhs,
+ const ReceivedBundleElementIterator& rhs );
+
+private:
+ ReceivedBundleElement value_;
+
+ void Advance() { value_.size_ = value_.Contents() + value_.Size(); }
+
+ bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const
+ {
+ return value_.size_ == rhs.value_.size_;
+ }
+};
+
+inline bool operator==(const ReceivedBundleElementIterator& lhs,
+ const ReceivedBundleElementIterator& rhs )
+{
+ return lhs.IsEqualTo( rhs );
+}
+
+inline bool operator!=(const ReceivedBundleElementIterator& lhs,
+ const ReceivedBundleElementIterator& rhs )
+{
+ return !( lhs == rhs );
+}
+
+
+class ReceivedMessageArgument{
+public:
+ ReceivedMessageArgument( const char *typeTag, const char *argument )
+ : typeTag_( typeTag )
+ , argument_( argument ) {}
+
+ friend class ReceivedMessageArgumentIterator;
+
+ const char TypeTag() const { return *typeTag_; }
+
+ // the unchecked methods below don't check whether the argument actually
+ // is of the specified type. they should only be used if you've already
+ // checked the type tag or the associated IsType() method.
+
+ bool IsBool() const
+ { return *typeTag_ == TRUE_TYPE_TAG || *typeTag_ == FALSE_TYPE_TAG; }
+ bool AsBool() const;
+ bool AsBoolUnchecked() const;
+
+ bool IsNil() const { return *typeTag_ == NIL_TYPE_TAG; }
+ bool IsInfinitum() const { return *typeTag_ == INFINITUM_TYPE_TAG; }
+
+ bool IsInt32() const { return *typeTag_ == INT32_TYPE_TAG; }
+ int32 AsInt32() const;
+ int32 AsInt32Unchecked() const;
+
+ bool IsFloat() const { return *typeTag_ == FLOAT_TYPE_TAG; }
+ float AsFloat() const;
+ float AsFloatUnchecked() const;
+
+ bool IsChar() const { return *typeTag_ == CHAR_TYPE_TAG; }
+ char AsChar() const;
+ char AsCharUnchecked() const;
+
+ bool IsRgbaColor() const { return *typeTag_ == RGBA_COLOR_TYPE_TAG; }
+ uint32 AsRgbaColor() const;
+ uint32 AsRgbaColorUnchecked() const;
+
+ bool IsMidiMessage() const { return *typeTag_ == MIDI_MESSAGE_TYPE_TAG; }
+ uint32 AsMidiMessage() const;
+ uint32 AsMidiMessageUnchecked() const;
+
+ bool IsInt64() const { return *typeTag_ == INT64_TYPE_TAG; }
+ int64 AsInt64() const;
+ int64 AsInt64Unchecked() const;
+
+ bool IsTimeTag() const { return *typeTag_ == TIME_TAG_TYPE_TAG; }
+ uint64 AsTimeTag() const;
+ uint64 AsTimeTagUnchecked() const;
+
+ bool IsDouble() const { return *typeTag_ == DOUBLE_TYPE_TAG; }
+ double AsDouble() const;
+ double AsDoubleUnchecked() const;
+
+ bool IsString() const { return *typeTag_ == STRING_TYPE_TAG; }
+ const char* AsString() const;
+ const char* AsStringUnchecked() const { return argument_; }
+
+ bool IsSymbol() const { return *typeTag_ == SYMBOL_TYPE_TAG; }
+ const char* AsSymbol() const;
+ const char* AsSymbolUnchecked() const { return argument_; }
+
+ bool IsBlob() const { return *typeTag_ == BLOB_TYPE_TAG; }
+ void AsBlob( const void*& data, unsigned long& size ) const;
+ void AsBlobUnchecked( const void*& data, unsigned long& size ) const;
+
+private:
+ const char *typeTag_;
+ const char *argument_;
+};
+
+
+class ReceivedMessageArgumentIterator{
+public:
+ ReceivedMessageArgumentIterator( const char *typeTags, const char *arguments )
+ : value_( typeTags, arguments ) {}
+
+ ReceivedMessageArgumentIterator operator++()
+ {
+ Advance();
+ return *this;
+ }
+
+ ReceivedMessageArgumentIterator operator++(int)
+ {
+ ReceivedMessageArgumentIterator old( *this );
+ Advance();
+ return old;
+ }
+
+ const ReceivedMessageArgument& operator*() const { return value_; }
+
+ const ReceivedMessageArgument* operator->() const { return &value_; }
+
+ friend bool operator==(const ReceivedMessageArgumentIterator& lhs,
+ const ReceivedMessageArgumentIterator& rhs );
+
+private:
+ ReceivedMessageArgument value_;
+
+ void Advance();
+
+ bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const
+ {
+ return value_.typeTag_ == rhs.value_.typeTag_;
+ }
+};
+
+inline bool operator==(const ReceivedMessageArgumentIterator& lhs,
+ const ReceivedMessageArgumentIterator& rhs )
+{
+ return lhs.IsEqualTo( rhs );
+}
+
+inline bool operator!=(const ReceivedMessageArgumentIterator& lhs,
+ const ReceivedMessageArgumentIterator& rhs )
+{
+ return !( lhs == rhs );
+}
+
+
+class ReceivedMessageArgumentStream{
+ friend class ReceivedMessage;
+ ReceivedMessageArgumentStream( const ReceivedMessageArgumentIterator& begin,
+ const ReceivedMessageArgumentIterator& end )
+ : p_( begin )
+ , end_( end ) {}
+
+ ReceivedMessageArgumentIterator p_, end_;
+
+public:
+
+ // end of stream
+ bool Eos() const { return p_ == end_; }
+
+ ReceivedMessageArgumentStream& operator>>( bool& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs = (*p_++).AsBool();
+ return *this;
+ }
+
+ // not sure if it would be useful to stream Nil and Infinitum
+ // for now it's not possible
+
+ ReceivedMessageArgumentStream& operator>>( int32& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs = (*p_++).AsInt32();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( float& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs = (*p_++).AsFloat();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( char& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs = (*p_++).AsChar();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( RgbaColor& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs.value = (*p_++).AsRgbaColor();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( MidiMessage& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs.value = (*p_++).AsMidiMessage();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( int64& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs = (*p_++).AsInt64();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( TimeTag& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs.value = (*p_++).AsTimeTag();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( double& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs = (*p_++).AsDouble();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( Blob& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ (*p_++).AsBlob( rhs.data, rhs.size );
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( const char*& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs = (*p_++).AsString();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( Symbol& rhs )
+ {
+ if( Eos() )
+ throw MissingArgumentException();
+
+ rhs.value = (*p_++).AsSymbol();
+ return *this;
+ }
+
+ ReceivedMessageArgumentStream& operator>>( MessageTerminator& rhs )
+ {
+ if( !Eos() )
+ throw ExcessArgumentException();
+
+ return *this;
+ }
+};
+
+
+class ReceivedMessage{
+ void Init( const char *bundle, unsigned long size );
+public:
+ explicit ReceivedMessage( const ReceivedPacket& packet );
+ explicit ReceivedMessage( const ReceivedBundleElement& bundleElement );
+
+ const char *AddressPattern() const { return addressPattern_; }
+
+ // Support for non-standad SuperCollider integer address patterns:
+ bool AddressPatternIsUInt32() const;
+ uint32 AddressPatternAsUInt32() const;
+
+ unsigned long ArgumentCount() const { return static_cast<unsigned long>(typeTagsEnd_ - typeTagsBegin_); }
+
+ const char *TypeTags() const { return typeTagsBegin_; }
+
+
+ typedef ReceivedMessageArgumentIterator const_iterator;
+
+ ReceivedMessageArgumentIterator ArgumentsBegin() const
+ {
+ return ReceivedMessageArgumentIterator( typeTagsBegin_, arguments_ );
+ }
+
+ ReceivedMessageArgumentIterator ArgumentsEnd() const
+ {
+ return ReceivedMessageArgumentIterator( typeTagsEnd_, 0 );
+ }
+
+ ReceivedMessageArgumentStream ArgumentStream() const
+ {
+ return ReceivedMessageArgumentStream( ArgumentsBegin(), ArgumentsEnd() );
+ }
+
+private:
+ const char *addressPattern_;
+ const char *typeTagsBegin_;
+ const char *typeTagsEnd_;
+ const char *arguments_;
+};
+
+
+class ReceivedBundle{
+ void Init( const char *message, unsigned long size );
+public:
+ explicit ReceivedBundle( const ReceivedPacket& packet );
+ explicit ReceivedBundle( const ReceivedBundleElement& bundleElement );
+
+ uint64 TimeTag() const;
+
+ unsigned long ElementCount() const { return elementCount_; }
+
+ typedef ReceivedBundleElementIterator const_iterator;
+
+ ReceivedBundleElementIterator ElementsBegin() const
+ {
+ return ReceivedBundleElementIterator( timeTag_ + 8 );
+ }
+
+ ReceivedBundleElementIterator ElementsEnd() const
+ {
+ return ReceivedBundleElementIterator( end_ );
+ }
+
+private:
+ const char *timeTag_;
+ const char *end_;
+ unsigned long elementCount_;
+};
+
+
+} // namespace osc
+
+
+#endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */