annotate addons/ofxOsc/libs/oscpack/include/osc/OscReceivedElements.h @ 52:13194a9dca77 tip

Added exporting of image and text data
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Tue, 17 Jul 2012 22:13:10 +0100
parents b299a65a3ad0
children
rev   line source
andrew@0 1 /*
andrew@0 2 oscpack -- Open Sound Control packet manipulation library
andrew@0 3 http://www.audiomulch.com/~rossb/oscpack
andrew@0 4
andrew@0 5 Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
andrew@0 6
andrew@0 7 Permission is hereby granted, free of charge, to any person obtaining
andrew@0 8 a copy of this software and associated documentation files
andrew@0 9 (the "Software"), to deal in the Software without restriction,
andrew@0 10 including without limitation the rights to use, copy, modify, merge,
andrew@0 11 publish, distribute, sublicense, and/or sell copies of the Software,
andrew@0 12 and to permit persons to whom the Software is furnished to do so,
andrew@0 13 subject to the following conditions:
andrew@0 14
andrew@0 15 The above copyright notice and this permission notice shall be
andrew@0 16 included in all copies or substantial portions of the Software.
andrew@0 17
andrew@0 18 Any person wishing to distribute modifications to the Software is
andrew@0 19 requested to send the modifications to the original developer so that
andrew@0 20 they can be incorporated into the canonical version.
andrew@0 21
andrew@0 22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
andrew@0 23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
andrew@0 24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
andrew@0 25 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
andrew@0 26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
andrew@0 27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
andrew@0 28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
andrew@0 29 */
andrew@0 30 #ifndef INCLUDED_OSCRECEIVEDELEMENTS_H
andrew@0 31 #define INCLUDED_OSCRECEIVEDELEMENTS_H
andrew@0 32
andrew@0 33 #include "OscTypes.h"
andrew@0 34 #include "OscException.h"
andrew@0 35
andrew@0 36
andrew@0 37 namespace osc{
andrew@0 38
andrew@0 39
andrew@0 40 class MalformedMessageException : public Exception{
andrew@0 41 public:
andrew@0 42 MalformedMessageException( const char *w="malformed message" )
andrew@0 43 : Exception( w ) {}
andrew@0 44 };
andrew@0 45
andrew@0 46 class MalformedBundleException : public Exception{
andrew@0 47 public:
andrew@0 48 MalformedBundleException( const char *w="malformed bundle" )
andrew@0 49 : Exception( w ) {}
andrew@0 50 };
andrew@0 51
andrew@0 52 class WrongArgumentTypeException : public Exception{
andrew@0 53 public:
andrew@0 54 WrongArgumentTypeException( const char *w="wrong argument type" )
andrew@0 55 : Exception( w ) {}
andrew@0 56 };
andrew@0 57
andrew@0 58 class MissingArgumentException : public Exception{
andrew@0 59 public:
andrew@0 60 MissingArgumentException( const char *w="missing argument" )
andrew@0 61 : Exception( w ) {}
andrew@0 62 };
andrew@0 63
andrew@0 64 class ExcessArgumentException : public Exception{
andrew@0 65 public:
andrew@0 66 ExcessArgumentException( const char *w="too many arguments" )
andrew@0 67 : Exception( w ) {}
andrew@0 68 };
andrew@0 69
andrew@0 70
andrew@0 71 class ReceivedPacket{
andrew@0 72 public:
andrew@0 73 ReceivedPacket( const char *contents, int32 size )
andrew@0 74 : contents_( contents )
andrew@0 75 , size_( size ) {}
andrew@0 76
andrew@0 77 bool IsMessage() const { return !IsBundle(); }
andrew@0 78 bool IsBundle() const;
andrew@0 79
andrew@0 80 int32 Size() const { return size_; }
andrew@0 81 const char *Contents() const { return contents_; }
andrew@0 82
andrew@0 83 private:
andrew@0 84 const char *contents_;
andrew@0 85 int32 size_;
andrew@0 86 };
andrew@0 87
andrew@0 88
andrew@0 89 class ReceivedBundleElement{
andrew@0 90 public:
andrew@0 91 ReceivedBundleElement( const char *size )
andrew@0 92 : size_( size ) {}
andrew@0 93
andrew@0 94 friend class ReceivedBundleElementIterator;
andrew@0 95
andrew@0 96 bool IsMessage() const { return !IsBundle(); }
andrew@0 97 bool IsBundle() const;
andrew@0 98
andrew@0 99 int32 Size() const;
andrew@0 100 const char *Contents() const { return size_ + 4; }
andrew@0 101
andrew@0 102 private:
andrew@0 103 const char *size_;
andrew@0 104 };
andrew@0 105
andrew@0 106
andrew@0 107 class ReceivedBundleElementIterator{
andrew@0 108 public:
andrew@0 109 ReceivedBundleElementIterator( const char *sizePtr )
andrew@0 110 : value_( sizePtr ) {}
andrew@0 111
andrew@0 112 ReceivedBundleElementIterator operator++()
andrew@0 113 {
andrew@0 114 Advance();
andrew@0 115 return *this;
andrew@0 116 }
andrew@0 117
andrew@0 118 ReceivedBundleElementIterator operator++(int)
andrew@0 119 {
andrew@0 120 ReceivedBundleElementIterator old( *this );
andrew@0 121 Advance();
andrew@0 122 return old;
andrew@0 123 }
andrew@0 124
andrew@0 125 const ReceivedBundleElement& operator*() const { return value_; }
andrew@0 126
andrew@0 127 const ReceivedBundleElement* operator->() const { return &value_; }
andrew@0 128
andrew@0 129 friend bool operator==(const ReceivedBundleElementIterator& lhs,
andrew@0 130 const ReceivedBundleElementIterator& rhs );
andrew@0 131
andrew@0 132 private:
andrew@0 133 ReceivedBundleElement value_;
andrew@0 134
andrew@0 135 void Advance() { value_.size_ = value_.Contents() + value_.Size(); }
andrew@0 136
andrew@0 137 bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const
andrew@0 138 {
andrew@0 139 return value_.size_ == rhs.value_.size_;
andrew@0 140 }
andrew@0 141 };
andrew@0 142
andrew@0 143 inline bool operator==(const ReceivedBundleElementIterator& lhs,
andrew@0 144 const ReceivedBundleElementIterator& rhs )
andrew@0 145 {
andrew@0 146 return lhs.IsEqualTo( rhs );
andrew@0 147 }
andrew@0 148
andrew@0 149 inline bool operator!=(const ReceivedBundleElementIterator& lhs,
andrew@0 150 const ReceivedBundleElementIterator& rhs )
andrew@0 151 {
andrew@0 152 return !( lhs == rhs );
andrew@0 153 }
andrew@0 154
andrew@0 155
andrew@0 156 class ReceivedMessageArgument{
andrew@0 157 public:
andrew@0 158 ReceivedMessageArgument( const char *typeTag, const char *argument )
andrew@0 159 : typeTag_( typeTag )
andrew@0 160 , argument_( argument ) {}
andrew@0 161
andrew@0 162 friend class ReceivedMessageArgumentIterator;
andrew@0 163
andrew@0 164 const char TypeTag() const { return *typeTag_; }
andrew@0 165
andrew@0 166 // the unchecked methods below don't check whether the argument actually
andrew@0 167 // is of the specified type. they should only be used if you've already
andrew@0 168 // checked the type tag or the associated IsType() method.
andrew@0 169
andrew@0 170 bool IsBool() const
andrew@0 171 { return *typeTag_ == TRUE_TYPE_TAG || *typeTag_ == FALSE_TYPE_TAG; }
andrew@0 172 bool AsBool() const;
andrew@0 173 bool AsBoolUnchecked() const;
andrew@0 174
andrew@0 175 bool IsNil() const { return *typeTag_ == NIL_TYPE_TAG; }
andrew@0 176 bool IsInfinitum() const { return *typeTag_ == INFINITUM_TYPE_TAG; }
andrew@0 177
andrew@0 178 bool IsInt32() const { return *typeTag_ == INT32_TYPE_TAG; }
andrew@0 179 int32 AsInt32() const;
andrew@0 180 int32 AsInt32Unchecked() const;
andrew@0 181
andrew@0 182 bool IsFloat() const { return *typeTag_ == FLOAT_TYPE_TAG; }
andrew@0 183 float AsFloat() const;
andrew@0 184 float AsFloatUnchecked() const;
andrew@0 185
andrew@0 186 bool IsChar() const { return *typeTag_ == CHAR_TYPE_TAG; }
andrew@0 187 char AsChar() const;
andrew@0 188 char AsCharUnchecked() const;
andrew@0 189
andrew@0 190 bool IsRgbaColor() const { return *typeTag_ == RGBA_COLOR_TYPE_TAG; }
andrew@0 191 uint32 AsRgbaColor() const;
andrew@0 192 uint32 AsRgbaColorUnchecked() const;
andrew@0 193
andrew@0 194 bool IsMidiMessage() const { return *typeTag_ == MIDI_MESSAGE_TYPE_TAG; }
andrew@0 195 uint32 AsMidiMessage() const;
andrew@0 196 uint32 AsMidiMessageUnchecked() const;
andrew@0 197
andrew@0 198 bool IsInt64() const { return *typeTag_ == INT64_TYPE_TAG; }
andrew@0 199 int64 AsInt64() const;
andrew@0 200 int64 AsInt64Unchecked() const;
andrew@0 201
andrew@0 202 bool IsTimeTag() const { return *typeTag_ == TIME_TAG_TYPE_TAG; }
andrew@0 203 uint64 AsTimeTag() const;
andrew@0 204 uint64 AsTimeTagUnchecked() const;
andrew@0 205
andrew@0 206 bool IsDouble() const { return *typeTag_ == DOUBLE_TYPE_TAG; }
andrew@0 207 double AsDouble() const;
andrew@0 208 double AsDoubleUnchecked() const;
andrew@0 209
andrew@0 210 bool IsString() const { return *typeTag_ == STRING_TYPE_TAG; }
andrew@0 211 const char* AsString() const;
andrew@0 212 const char* AsStringUnchecked() const { return argument_; }
andrew@0 213
andrew@0 214 bool IsSymbol() const { return *typeTag_ == SYMBOL_TYPE_TAG; }
andrew@0 215 const char* AsSymbol() const;
andrew@0 216 const char* AsSymbolUnchecked() const { return argument_; }
andrew@0 217
andrew@0 218 bool IsBlob() const { return *typeTag_ == BLOB_TYPE_TAG; }
andrew@0 219 void AsBlob( const void*& data, unsigned long& size ) const;
andrew@0 220 void AsBlobUnchecked( const void*& data, unsigned long& size ) const;
andrew@0 221
andrew@0 222 private:
andrew@0 223 const char *typeTag_;
andrew@0 224 const char *argument_;
andrew@0 225 };
andrew@0 226
andrew@0 227
andrew@0 228 class ReceivedMessageArgumentIterator{
andrew@0 229 public:
andrew@0 230 ReceivedMessageArgumentIterator( const char *typeTags, const char *arguments )
andrew@0 231 : value_( typeTags, arguments ) {}
andrew@0 232
andrew@0 233 ReceivedMessageArgumentIterator operator++()
andrew@0 234 {
andrew@0 235 Advance();
andrew@0 236 return *this;
andrew@0 237 }
andrew@0 238
andrew@0 239 ReceivedMessageArgumentIterator operator++(int)
andrew@0 240 {
andrew@0 241 ReceivedMessageArgumentIterator old( *this );
andrew@0 242 Advance();
andrew@0 243 return old;
andrew@0 244 }
andrew@0 245
andrew@0 246 const ReceivedMessageArgument& operator*() const { return value_; }
andrew@0 247
andrew@0 248 const ReceivedMessageArgument* operator->() const { return &value_; }
andrew@0 249
andrew@0 250 friend bool operator==(const ReceivedMessageArgumentIterator& lhs,
andrew@0 251 const ReceivedMessageArgumentIterator& rhs );
andrew@0 252
andrew@0 253 private:
andrew@0 254 ReceivedMessageArgument value_;
andrew@0 255
andrew@0 256 void Advance();
andrew@0 257
andrew@0 258 bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const
andrew@0 259 {
andrew@0 260 return value_.typeTag_ == rhs.value_.typeTag_;
andrew@0 261 }
andrew@0 262 };
andrew@0 263
andrew@0 264 inline bool operator==(const ReceivedMessageArgumentIterator& lhs,
andrew@0 265 const ReceivedMessageArgumentIterator& rhs )
andrew@0 266 {
andrew@0 267 return lhs.IsEqualTo( rhs );
andrew@0 268 }
andrew@0 269
andrew@0 270 inline bool operator!=(const ReceivedMessageArgumentIterator& lhs,
andrew@0 271 const ReceivedMessageArgumentIterator& rhs )
andrew@0 272 {
andrew@0 273 return !( lhs == rhs );
andrew@0 274 }
andrew@0 275
andrew@0 276
andrew@0 277 class ReceivedMessageArgumentStream{
andrew@0 278 friend class ReceivedMessage;
andrew@0 279 ReceivedMessageArgumentStream( const ReceivedMessageArgumentIterator& begin,
andrew@0 280 const ReceivedMessageArgumentIterator& end )
andrew@0 281 : p_( begin )
andrew@0 282 , end_( end ) {}
andrew@0 283
andrew@0 284 ReceivedMessageArgumentIterator p_, end_;
andrew@0 285
andrew@0 286 public:
andrew@0 287
andrew@0 288 // end of stream
andrew@0 289 bool Eos() const { return p_ == end_; }
andrew@0 290
andrew@0 291 ReceivedMessageArgumentStream& operator>>( bool& rhs )
andrew@0 292 {
andrew@0 293 if( Eos() )
andrew@0 294 throw MissingArgumentException();
andrew@0 295
andrew@0 296 rhs = (*p_++).AsBool();
andrew@0 297 return *this;
andrew@0 298 }
andrew@0 299
andrew@0 300 // not sure if it would be useful to stream Nil and Infinitum
andrew@0 301 // for now it's not possible
andrew@0 302
andrew@0 303 ReceivedMessageArgumentStream& operator>>( int32& rhs )
andrew@0 304 {
andrew@0 305 if( Eos() )
andrew@0 306 throw MissingArgumentException();
andrew@0 307
andrew@0 308 rhs = (*p_++).AsInt32();
andrew@0 309 return *this;
andrew@0 310 }
andrew@0 311
andrew@0 312 ReceivedMessageArgumentStream& operator>>( float& rhs )
andrew@0 313 {
andrew@0 314 if( Eos() )
andrew@0 315 throw MissingArgumentException();
andrew@0 316
andrew@0 317 rhs = (*p_++).AsFloat();
andrew@0 318 return *this;
andrew@0 319 }
andrew@0 320
andrew@0 321 ReceivedMessageArgumentStream& operator>>( char& rhs )
andrew@0 322 {
andrew@0 323 if( Eos() )
andrew@0 324 throw MissingArgumentException();
andrew@0 325
andrew@0 326 rhs = (*p_++).AsChar();
andrew@0 327 return *this;
andrew@0 328 }
andrew@0 329
andrew@0 330 ReceivedMessageArgumentStream& operator>>( RgbaColor& rhs )
andrew@0 331 {
andrew@0 332 if( Eos() )
andrew@0 333 throw MissingArgumentException();
andrew@0 334
andrew@0 335 rhs.value = (*p_++).AsRgbaColor();
andrew@0 336 return *this;
andrew@0 337 }
andrew@0 338
andrew@0 339 ReceivedMessageArgumentStream& operator>>( MidiMessage& rhs )
andrew@0 340 {
andrew@0 341 if( Eos() )
andrew@0 342 throw MissingArgumentException();
andrew@0 343
andrew@0 344 rhs.value = (*p_++).AsMidiMessage();
andrew@0 345 return *this;
andrew@0 346 }
andrew@0 347
andrew@0 348 ReceivedMessageArgumentStream& operator>>( int64& rhs )
andrew@0 349 {
andrew@0 350 if( Eos() )
andrew@0 351 throw MissingArgumentException();
andrew@0 352
andrew@0 353 rhs = (*p_++).AsInt64();
andrew@0 354 return *this;
andrew@0 355 }
andrew@0 356
andrew@0 357 ReceivedMessageArgumentStream& operator>>( TimeTag& rhs )
andrew@0 358 {
andrew@0 359 if( Eos() )
andrew@0 360 throw MissingArgumentException();
andrew@0 361
andrew@0 362 rhs.value = (*p_++).AsTimeTag();
andrew@0 363 return *this;
andrew@0 364 }
andrew@0 365
andrew@0 366 ReceivedMessageArgumentStream& operator>>( double& rhs )
andrew@0 367 {
andrew@0 368 if( Eos() )
andrew@0 369 throw MissingArgumentException();
andrew@0 370
andrew@0 371 rhs = (*p_++).AsDouble();
andrew@0 372 return *this;
andrew@0 373 }
andrew@0 374
andrew@0 375 ReceivedMessageArgumentStream& operator>>( Blob& rhs )
andrew@0 376 {
andrew@0 377 if( Eos() )
andrew@0 378 throw MissingArgumentException();
andrew@0 379
andrew@0 380 (*p_++).AsBlob( rhs.data, rhs.size );
andrew@0 381 return *this;
andrew@0 382 }
andrew@0 383
andrew@0 384 ReceivedMessageArgumentStream& operator>>( const char*& rhs )
andrew@0 385 {
andrew@0 386 if( Eos() )
andrew@0 387 throw MissingArgumentException();
andrew@0 388
andrew@0 389 rhs = (*p_++).AsString();
andrew@0 390 return *this;
andrew@0 391 }
andrew@0 392
andrew@0 393 ReceivedMessageArgumentStream& operator>>( Symbol& rhs )
andrew@0 394 {
andrew@0 395 if( Eos() )
andrew@0 396 throw MissingArgumentException();
andrew@0 397
andrew@0 398 rhs.value = (*p_++).AsSymbol();
andrew@0 399 return *this;
andrew@0 400 }
andrew@0 401
andrew@0 402 ReceivedMessageArgumentStream& operator>>( MessageTerminator& rhs )
andrew@0 403 {
andrew@0 404 if( !Eos() )
andrew@0 405 throw ExcessArgumentException();
andrew@0 406
andrew@0 407 return *this;
andrew@0 408 }
andrew@0 409 };
andrew@0 410
andrew@0 411
andrew@0 412 class ReceivedMessage{
andrew@0 413 void Init( const char *bundle, unsigned long size );
andrew@0 414 public:
andrew@0 415 explicit ReceivedMessage( const ReceivedPacket& packet );
andrew@0 416 explicit ReceivedMessage( const ReceivedBundleElement& bundleElement );
andrew@0 417
andrew@0 418 const char *AddressPattern() const { return addressPattern_; }
andrew@0 419
andrew@0 420 // Support for non-standad SuperCollider integer address patterns:
andrew@0 421 bool AddressPatternIsUInt32() const;
andrew@0 422 uint32 AddressPatternAsUInt32() const;
andrew@0 423
andrew@0 424 unsigned long ArgumentCount() const { return static_cast<unsigned long>(typeTagsEnd_ - typeTagsBegin_); }
andrew@0 425
andrew@0 426 const char *TypeTags() const { return typeTagsBegin_; }
andrew@0 427
andrew@0 428
andrew@0 429 typedef ReceivedMessageArgumentIterator const_iterator;
andrew@0 430
andrew@0 431 ReceivedMessageArgumentIterator ArgumentsBegin() const
andrew@0 432 {
andrew@0 433 return ReceivedMessageArgumentIterator( typeTagsBegin_, arguments_ );
andrew@0 434 }
andrew@0 435
andrew@0 436 ReceivedMessageArgumentIterator ArgumentsEnd() const
andrew@0 437 {
andrew@0 438 return ReceivedMessageArgumentIterator( typeTagsEnd_, 0 );
andrew@0 439 }
andrew@0 440
andrew@0 441 ReceivedMessageArgumentStream ArgumentStream() const
andrew@0 442 {
andrew@0 443 return ReceivedMessageArgumentStream( ArgumentsBegin(), ArgumentsEnd() );
andrew@0 444 }
andrew@0 445
andrew@0 446 private:
andrew@0 447 const char *addressPattern_;
andrew@0 448 const char *typeTagsBegin_;
andrew@0 449 const char *typeTagsEnd_;
andrew@0 450 const char *arguments_;
andrew@0 451 };
andrew@0 452
andrew@0 453
andrew@0 454 class ReceivedBundle{
andrew@0 455 void Init( const char *message, unsigned long size );
andrew@0 456 public:
andrew@0 457 explicit ReceivedBundle( const ReceivedPacket& packet );
andrew@0 458 explicit ReceivedBundle( const ReceivedBundleElement& bundleElement );
andrew@0 459
andrew@0 460 uint64 TimeTag() const;
andrew@0 461
andrew@0 462 unsigned long ElementCount() const { return elementCount_; }
andrew@0 463
andrew@0 464 typedef ReceivedBundleElementIterator const_iterator;
andrew@0 465
andrew@0 466 ReceivedBundleElementIterator ElementsBegin() const
andrew@0 467 {
andrew@0 468 return ReceivedBundleElementIterator( timeTag_ + 8 );
andrew@0 469 }
andrew@0 470
andrew@0 471 ReceivedBundleElementIterator ElementsEnd() const
andrew@0 472 {
andrew@0 473 return ReceivedBundleElementIterator( end_ );
andrew@0 474 }
andrew@0 475
andrew@0 476 private:
andrew@0 477 const char *timeTag_;
andrew@0 478 const char *end_;
andrew@0 479 unsigned long elementCount_;
andrew@0 480 };
andrew@0 481
andrew@0 482
andrew@0 483 } // namespace osc
andrew@0 484
andrew@0 485
andrew@0 486 #endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */