]> git.sesse.net Git - casparcg/blobdiff - protocol/osc/oscpack/OscReceivedElements.h
set svn:eol-style native on .h and .cpp files
[casparcg] / protocol / osc / oscpack / OscReceivedElements.h
index 07e01943d4e3abb22802e40cf93050a786888134..48364061049a51659c8982680aedb8aeabfe27f2 100644 (file)
-/*\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 */