Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef INCLUDED_OSCRECEIVEDELEMENTS_H
00031 #define INCLUDED_OSCRECEIVEDELEMENTS_H
00032
00033 #include "OscTypes.h"
00034 #include "OscException.h"
00035
00036
00037 namespace osc{
00038
00039
00040 class MalformedMessageException : public Exception{
00041 public:
00042 MalformedMessageException( const char *w="malformed message" )
00043 : Exception( w ) {}
00044 };
00045
00046 class MalformedBundleException : public Exception{
00047 public:
00048 MalformedBundleException( const char *w="malformed bundle" )
00049 : Exception( w ) {}
00050 };
00051
00052 class WrongArgumentTypeException : public Exception{
00053 public:
00054 WrongArgumentTypeException( const char *w="wrong argument type" )
00055 : Exception( w ) {}
00056 };
00057
00058 class MissingArgumentException : public Exception{
00059 public:
00060 MissingArgumentException( const char *w="missing argument" )
00061 : Exception( w ) {}
00062 };
00063
00064 class ExcessArgumentException : public Exception{
00065 public:
00066 ExcessArgumentException( const char *w="too many arguments" )
00067 : Exception( w ) {}
00068 };
00069
00070
00071 class ReceivedPacket{
00072 public:
00073 ReceivedPacket( const char *contents, int32 size )
00074 : contents_( contents )
00075 , size_( size ) {}
00076
00077 bool IsMessage() const { return !IsBundle(); }
00078 bool IsBundle() const;
00079
00080 int32 Size() const { return size_; }
00081 const char *Contents() const { return contents_; }
00082
00083 private:
00084 const char *contents_;
00085 int32 size_;
00086 };
00087
00088
00089 class ReceivedBundleElement{
00090 public:
00091 ReceivedBundleElement( const char *size )
00092 : size_( size ) {}
00093
00094 friend class ReceivedBundleElementIterator;
00095
00096 bool IsMessage() const { return !IsBundle(); }
00097 bool IsBundle() const;
00098
00099 int32 Size() const;
00100 const char *Contents() const { return size_ + 4; }
00101
00102 private:
00103 const char *size_;
00104 };
00105
00106
00107 class ReceivedBundleElementIterator{
00108 public:
00109 ReceivedBundleElementIterator( const char *sizePtr )
00110 : value_( sizePtr ) {}
00111
00112 ReceivedBundleElementIterator operator++()
00113 {
00114 Advance();
00115 return *this;
00116 }
00117
00118 ReceivedBundleElementIterator operator++(int)
00119 {
00120 ReceivedBundleElementIterator old( *this );
00121 Advance();
00122 return old;
00123 }
00124
00125 const ReceivedBundleElement& operator*() const { return value_; }
00126
00127 const ReceivedBundleElement* operator->() const { return &value_; }
00128
00129 friend bool operator==(const ReceivedBundleElementIterator& lhs,
00130 const ReceivedBundleElementIterator& rhs );
00131
00132 private:
00133 ReceivedBundleElement value_;
00134
00135 void Advance() { value_.size_ = value_.Contents() + value_.Size(); }
00136
00137 bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const
00138 {
00139 return value_.size_ == rhs.value_.size_;
00140 }
00141 };
00142
00143 inline bool operator==(const ReceivedBundleElementIterator& lhs,
00144 const ReceivedBundleElementIterator& rhs )
00145 {
00146 return lhs.IsEqualTo( rhs );
00147 }
00148
00149 inline bool operator!=(const ReceivedBundleElementIterator& lhs,
00150 const ReceivedBundleElementIterator& rhs )
00151 {
00152 return !( lhs == rhs );
00153 }
00154
00155
00156 class ReceivedMessageArgument{
00157 public:
00158 ReceivedMessageArgument( const char *typeTag, const char *argument )
00159 : typeTag_( typeTag )
00160 , argument_( argument ) {}
00161
00162 friend class ReceivedMessageArgumentIterator;
00163
00164 const char TypeTag() const { return *typeTag_; }
00165
00166
00167
00168
00169
00170 bool IsBool() const
00171 { return *typeTag_ == TRUE_TYPE_TAG || *typeTag_ == FALSE_TYPE_TAG; }
00172 bool AsBool() const;
00173 bool AsBoolUnchecked() const;
00174
00175 bool IsNil() const { return *typeTag_ == NIL_TYPE_TAG; }
00176 bool IsInfinitum() const { return *typeTag_ == INFINITUM_TYPE_TAG; }
00177
00178 bool IsInt32() const { return *typeTag_ == INT32_TYPE_TAG; }
00179 int32 AsInt32() const;
00180 int32 AsInt32Unchecked() const;
00181
00182 bool IsFloat() const { return *typeTag_ == FLOAT_TYPE_TAG; }
00183 float AsFloat() const;
00184 float AsFloatUnchecked() const;
00185
00186 bool IsChar() const { return *typeTag_ == CHAR_TYPE_TAG; }
00187 char AsChar() const;
00188 char AsCharUnchecked() const;
00189
00190 bool IsRgbaColor() const { return *typeTag_ == RGBA_COLOR_TYPE_TAG; }
00191 uint32 AsRgbaColor() const;
00192 uint32 AsRgbaColorUnchecked() const;
00193
00194 bool IsMidiMessage() const { return *typeTag_ == MIDI_MESSAGE_TYPE_TAG; }
00195 uint32 AsMidiMessage() const;
00196 uint32 AsMidiMessageUnchecked() const;
00197
00198 bool IsInt64() const { return *typeTag_ == INT64_TYPE_TAG; }
00199 int64 AsInt64() const;
00200 int64 AsInt64Unchecked() const;
00201
00202 bool IsTimeTag() const { return *typeTag_ == TIME_TAG_TYPE_TAG; }
00203 uint64 AsTimeTag() const;
00204 uint64 AsTimeTagUnchecked() const;
00205
00206 bool IsDouble() const { return *typeTag_ == DOUBLE_TYPE_TAG; }
00207 double AsDouble() const;
00208 double AsDoubleUnchecked() const;
00209
00210 bool IsString() const { return *typeTag_ == STRING_TYPE_TAG; }
00211 const char* AsString() const;
00212 const char* AsStringUnchecked() const { return argument_; }
00213
00214 bool IsSymbol() const { return *typeTag_ == SYMBOL_TYPE_TAG; }
00215 const char* AsSymbol() const;
00216 const char* AsSymbolUnchecked() const { return argument_; }
00217
00218 bool IsBlob() const { return *typeTag_ == BLOB_TYPE_TAG; }
00219 void AsBlob( const void*& data, unsigned long& size ) const;
00220 void AsBlobUnchecked( const void*& data, unsigned long& size ) const;
00221
00222 private:
00223 const char *typeTag_;
00224 const char *argument_;
00225 };
00226
00227
00228 class ReceivedMessageArgumentIterator{
00229 public:
00230 ReceivedMessageArgumentIterator( const char *typeTags, const char *arguments )
00231 : value_( typeTags, arguments ) {}
00232
00233 ReceivedMessageArgumentIterator operator++()
00234 {
00235 Advance();
00236 return *this;
00237 }
00238
00239 ReceivedMessageArgumentIterator operator++(int)
00240 {
00241 ReceivedMessageArgumentIterator old( *this );
00242 Advance();
00243 return old;
00244 }
00245
00246 const ReceivedMessageArgument& operator*() const { return value_; }
00247
00248 const ReceivedMessageArgument* operator->() const { return &value_; }
00249
00250 friend bool operator==(const ReceivedMessageArgumentIterator& lhs,
00251 const ReceivedMessageArgumentIterator& rhs );
00252
00253 private:
00254 ReceivedMessageArgument value_;
00255
00256 void Advance();
00257
00258 bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const
00259 {
00260 return value_.typeTag_ == rhs.value_.typeTag_;
00261 }
00262 };
00263
00264 inline bool operator==(const ReceivedMessageArgumentIterator& lhs,
00265 const ReceivedMessageArgumentIterator& rhs )
00266 {
00267 return lhs.IsEqualTo( rhs );
00268 }
00269
00270 inline bool operator!=(const ReceivedMessageArgumentIterator& lhs,
00271 const ReceivedMessageArgumentIterator& rhs )
00272 {
00273 return !( lhs == rhs );
00274 }
00275
00276
00277 class ReceivedMessageArgumentStream{
00278 friend class ReceivedMessage;
00279 ReceivedMessageArgumentStream( const ReceivedMessageArgumentIterator& begin,
00280 const ReceivedMessageArgumentIterator& end )
00281 : p_( begin )
00282 , end_( end ) {}
00283
00284 ReceivedMessageArgumentIterator p_, end_;
00285
00286 public:
00287
00288
00289 bool Eos() const { return p_ == end_; }
00290
00291 ReceivedMessageArgumentStream& operator>>( bool& rhs )
00292 {
00293 if( Eos() )
00294 throw MissingArgumentException();
00295
00296 rhs = (*p_++).AsBool();
00297 return *this;
00298 }
00299
00300
00301
00302
00303 ReceivedMessageArgumentStream& operator>>( int32& rhs )
00304 {
00305 if( Eos() )
00306 throw MissingArgumentException();
00307
00308 rhs = (*p_++).AsInt32();
00309 return *this;
00310 }
00311
00312 ReceivedMessageArgumentStream& operator>>( float& rhs )
00313 {
00314 if( Eos() )
00315 throw MissingArgumentException();
00316
00317 rhs = (*p_++).AsFloat();
00318 return *this;
00319 }
00320
00321 ReceivedMessageArgumentStream& operator>>( char& rhs )
00322 {
00323 if( Eos() )
00324 throw MissingArgumentException();
00325
00326 rhs = (*p_++).AsChar();
00327 return *this;
00328 }
00329
00330 ReceivedMessageArgumentStream& operator>>( RgbaColor& rhs )
00331 {
00332 if( Eos() )
00333 throw MissingArgumentException();
00334
00335 rhs.value = (*p_++).AsRgbaColor();
00336 return *this;
00337 }
00338
00339 ReceivedMessageArgumentStream& operator>>( MidiMessage& rhs )
00340 {
00341 if( Eos() )
00342 throw MissingArgumentException();
00343
00344 rhs.value = (*p_++).AsMidiMessage();
00345 return *this;
00346 }
00347
00348 ReceivedMessageArgumentStream& operator>>( int64& rhs )
00349 {
00350 if( Eos() )
00351 throw MissingArgumentException();
00352
00353 rhs = (*p_++).AsInt64();
00354 return *this;
00355 }
00356
00357 ReceivedMessageArgumentStream& operator>>( TimeTag& rhs )
00358 {
00359 if( Eos() )
00360 throw MissingArgumentException();
00361
00362 rhs.value = (*p_++).AsTimeTag();
00363 return *this;
00364 }
00365
00366 ReceivedMessageArgumentStream& operator>>( double& rhs )
00367 {
00368 if( Eos() )
00369 throw MissingArgumentException();
00370
00371 rhs = (*p_++).AsDouble();
00372 return *this;
00373 }
00374
00375 ReceivedMessageArgumentStream& operator>>( Blob& rhs )
00376 {
00377 if( Eos() )
00378 throw MissingArgumentException();
00379
00380 (*p_++).AsBlob( rhs.data, rhs.size );
00381 return *this;
00382 }
00383
00384 ReceivedMessageArgumentStream& operator>>( const char*& rhs )
00385 {
00386 if( Eos() )
00387 throw MissingArgumentException();
00388
00389 rhs = (*p_++).AsString();
00390 return *this;
00391 }
00392
00393 ReceivedMessageArgumentStream& operator>>( Symbol& rhs )
00394 {
00395 if( Eos() )
00396 throw MissingArgumentException();
00397
00398 rhs.value = (*p_++).AsSymbol();
00399 return *this;
00400 }
00401
00402 ReceivedMessageArgumentStream& operator>>( MessageTerminator& rhs )
00403 {
00404 if( !Eos() )
00405 throw ExcessArgumentException();
00406
00407 return *this;
00408 }
00409 };
00410
00411
00412 class ReceivedMessage{
00413 void Init( const char *bundle, unsigned long size );
00414 public:
00415 explicit ReceivedMessage( const ReceivedPacket& packet );
00416 explicit ReceivedMessage( const ReceivedBundleElement& bundleElement );
00417
00418 const char *AddressPattern() const { return addressPattern_; }
00419
00420
00421 bool AddressPatternIsUInt32() const;
00422 uint32 AddressPatternAsUInt32() const;
00423
00424 unsigned long ArgumentCount() const { return static_cast<unsigned long>(typeTagsEnd_ - typeTagsBegin_); }
00425
00426 const char *TypeTags() const { return typeTagsBegin_; }
00427
00428
00429 typedef ReceivedMessageArgumentIterator const_iterator;
00430
00431 ReceivedMessageArgumentIterator ArgumentsBegin() const
00432 {
00433 return ReceivedMessageArgumentIterator( typeTagsBegin_, arguments_ );
00434 }
00435
00436 ReceivedMessageArgumentIterator ArgumentsEnd() const
00437 {
00438 return ReceivedMessageArgumentIterator( typeTagsEnd_, 0 );
00439 }
00440
00441 ReceivedMessageArgumentStream ArgumentStream() const
00442 {
00443 return ReceivedMessageArgumentStream( ArgumentsBegin(), ArgumentsEnd() );
00444 }
00445
00446 private:
00447 const char *addressPattern_;
00448 const char *typeTagsBegin_;
00449 const char *typeTagsEnd_;
00450 const char *arguments_;
00451 };
00452
00453
00454 class ReceivedBundle{
00455 void Init( const char *message, unsigned long size );
00456 public:
00457 explicit ReceivedBundle( const ReceivedPacket& packet );
00458 explicit ReceivedBundle( const ReceivedBundleElement& bundleElement );
00459
00460 uint64 TimeTag() const;
00461
00462 unsigned long ElementCount() const { return elementCount_; }
00463
00464 typedef ReceivedBundleElementIterator const_iterator;
00465
00466 ReceivedBundleElementIterator ElementsBegin() const
00467 {
00468 return ReceivedBundleElementIterator( timeTag_ + 8 );
00469 }
00470
00471 ReceivedBundleElementIterator ElementsEnd() const
00472 {
00473 return ReceivedBundleElementIterator( end_ );
00474 }
00475
00476 private:
00477 const char *timeTag_;
00478 const char *end_;
00479 unsigned long elementCount_;
00480 };
00481
00482
00483 }
00484
00485
00486 #endif