| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486 |
- /*
- oscpack -- Open Sound Control packet manipulation library
- http://www.audiomulch.com/~rossb/oscpack
- Copyright (c) 2004-2005 Ross Bencina <[email protected]>
- 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 "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 */
|