2
oscpack -- Open Sound Control packet manipulation library
3
http://www.audiomulch.com/~rossb/oscpack
5
Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
7
Permission is hereby granted, free of charge, to any person obtaining
8
a copy of this software and associated documentation files
9
(the "Software"), to deal in the Software without restriction,
10
including without limitation the rights to use, copy, modify, merge,
11
publish, distribute, sublicense, and/or sell copies of the Software,
12
and to permit persons to whom the Software is furnished to do so,
13
subject to the following conditions:
15
The above copyright notice and this permission notice shall be
16
included in all copies or substantial portions of the Software.
18
Any person wishing to distribute modifications to the Software is
19
requested to send the modifications to the original developer so that
20
they can be incorporated into the canonical version.
22
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
26
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
27
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
#ifndef INCLUDED_OSCRECEIVEDELEMENTS_H
31
#define INCLUDED_OSCRECEIVEDELEMENTS_H
34
#include "OscException.h"
40
class MalformedMessageException : public Exception{
42
MalformedMessageException( const char *w="malformed message" )
46
class MalformedBundleException : public Exception{
48
MalformedBundleException( const char *w="malformed bundle" )
52
class WrongArgumentTypeException : public Exception{
54
WrongArgumentTypeException( const char *w="wrong argument type" )
58
class MissingArgumentException : public Exception{
60
MissingArgumentException( const char *w="missing argument" )
64
class ExcessArgumentException : public Exception{
66
ExcessArgumentException( const char *w="too many arguments" )
73
ReceivedPacket( const char *contents, int32 size )
74
: contents_( contents )
77
bool IsMessage() const { return !IsBundle(); }
78
bool IsBundle() const;
80
int32 Size() const { return size_; }
81
const char *Contents() const { return contents_; }
84
const char *contents_;
89
class ReceivedBundleElement{
91
ReceivedBundleElement( const char *size )
94
friend class ReceivedBundleElementIterator;
96
bool IsMessage() const { return !IsBundle(); }
97
bool IsBundle() const;
100
const char *Contents() const { return size_ + 4; }
107
class ReceivedBundleElementIterator{
109
ReceivedBundleElementIterator( const char *sizePtr )
110
: value_( sizePtr ) {}
112
ReceivedBundleElementIterator operator++()
118
ReceivedBundleElementIterator operator++(int)
120
ReceivedBundleElementIterator old( *this );
125
const ReceivedBundleElement& operator*() const { return value_; }
127
const ReceivedBundleElement* operator->() const { return &value_; }
129
friend bool operator==(const ReceivedBundleElementIterator& lhs,
130
const ReceivedBundleElementIterator& rhs );
133
ReceivedBundleElement value_;
135
void Advance() { value_.size_ = value_.Contents() + value_.Size(); }
137
bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const
139
return value_.size_ == rhs.value_.size_;
143
inline bool operator==(const ReceivedBundleElementIterator& lhs,
144
const ReceivedBundleElementIterator& rhs )
146
return lhs.IsEqualTo( rhs );
149
inline bool operator!=(const ReceivedBundleElementIterator& lhs,
150
const ReceivedBundleElementIterator& rhs )
152
return !( lhs == rhs );
156
class ReceivedMessageArgument{
158
ReceivedMessageArgument( const char *typeTag, const char *argument )
159
: typeTag_( typeTag )
160
, argument_( argument ) {}
162
friend class ReceivedMessageArgumentIterator;
164
const char TypeTag() const { return *typeTag_; }
166
// the unchecked methods below don't check whether the argument actually
167
// is of the specified type. they should only be used if you've already
168
// checked the type tag or the associated IsType() method.
171
{ return *typeTag_ == TRUE_TYPE_TAG || *typeTag_ == FALSE_TYPE_TAG; }
173
bool AsBoolUnchecked() const;
175
bool IsNil() const { return *typeTag_ == NIL_TYPE_TAG; }
176
bool IsInfinitum() const { return *typeTag_ == INFINITUM_TYPE_TAG; }
178
bool IsInt32() const { return *typeTag_ == INT32_TYPE_TAG; }
179
int32 AsInt32() const;
180
int32 AsInt32Unchecked() const;
182
bool IsFloat() const { return *typeTag_ == FLOAT_TYPE_TAG; }
183
float AsFloat() const;
184
float AsFloatUnchecked() const;
186
bool IsChar() const { return *typeTag_ == CHAR_TYPE_TAG; }
188
char AsCharUnchecked() const;
190
bool IsRgbaColor() const { return *typeTag_ == RGBA_COLOR_TYPE_TAG; }
191
uint32 AsRgbaColor() const;
192
uint32 AsRgbaColorUnchecked() const;
194
bool IsMidiMessage() const { return *typeTag_ == MIDI_MESSAGE_TYPE_TAG; }
195
uint32 AsMidiMessage() const;
196
uint32 AsMidiMessageUnchecked() const;
198
bool IsInt64() const { return *typeTag_ == INT64_TYPE_TAG; }
199
int64 AsInt64() const;
200
int64 AsInt64Unchecked() const;
202
bool IsTimeTag() const { return *typeTag_ == TIME_TAG_TYPE_TAG; }
203
uint64 AsTimeTag() const;
204
uint64 AsTimeTagUnchecked() const;
206
bool IsDouble() const { return *typeTag_ == DOUBLE_TYPE_TAG; }
207
double AsDouble() const;
208
double AsDoubleUnchecked() const;
210
bool IsString() const { return *typeTag_ == STRING_TYPE_TAG; }
211
const char* AsString() const;
212
const char* AsStringUnchecked() const { return argument_; }
214
bool IsSymbol() const { return *typeTag_ == SYMBOL_TYPE_TAG; }
215
const char* AsSymbol() const;
216
const char* AsSymbolUnchecked() const { return argument_; }
218
bool IsBlob() const { return *typeTag_ == BLOB_TYPE_TAG; }
219
void AsBlob( const void*& data, unsigned long& size ) const;
220
void AsBlobUnchecked( const void*& data, unsigned long& size ) const;
223
const char *typeTag_;
224
const char *argument_;
228
class ReceivedMessageArgumentIterator{
230
ReceivedMessageArgumentIterator( const char *typeTags, const char *arguments )
231
: value_( typeTags, arguments ) {}
233
ReceivedMessageArgumentIterator operator++()
239
ReceivedMessageArgumentIterator operator++(int)
241
ReceivedMessageArgumentIterator old( *this );
246
const ReceivedMessageArgument& operator*() const { return value_; }
248
const ReceivedMessageArgument* operator->() const { return &value_; }
250
friend bool operator==(const ReceivedMessageArgumentIterator& lhs,
251
const ReceivedMessageArgumentIterator& rhs );
254
ReceivedMessageArgument value_;
258
bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const
260
return value_.typeTag_ == rhs.value_.typeTag_;
264
inline bool operator==(const ReceivedMessageArgumentIterator& lhs,
265
const ReceivedMessageArgumentIterator& rhs )
267
return lhs.IsEqualTo( rhs );
270
inline bool operator!=(const ReceivedMessageArgumentIterator& lhs,
271
const ReceivedMessageArgumentIterator& rhs )
273
return !( lhs == rhs );
277
class ReceivedMessageArgumentStream{
278
friend class ReceivedMessage;
279
ReceivedMessageArgumentStream( const ReceivedMessageArgumentIterator& begin,
280
const ReceivedMessageArgumentIterator& end )
284
ReceivedMessageArgumentIterator p_, end_;
289
bool Eos() const { return p_ == end_; }
291
ReceivedMessageArgumentStream& operator>>( bool& rhs )
294
throw MissingArgumentException();
296
rhs = (*p_++).AsBool();
300
// not sure if it would be useful to stream Nil and Infinitum
301
// for now it's not possible
303
ReceivedMessageArgumentStream& operator>>( int32& rhs )
306
throw MissingArgumentException();
308
rhs = (*p_++).AsInt32();
312
ReceivedMessageArgumentStream& operator>>( float& rhs )
315
throw MissingArgumentException();
317
rhs = (*p_++).AsFloat();
321
ReceivedMessageArgumentStream& operator>>( char& rhs )
324
throw MissingArgumentException();
326
rhs = (*p_++).AsChar();
330
ReceivedMessageArgumentStream& operator>>( RgbaColor& rhs )
333
throw MissingArgumentException();
335
rhs.value = (*p_++).AsRgbaColor();
339
ReceivedMessageArgumentStream& operator>>( MidiMessage& rhs )
342
throw MissingArgumentException();
344
rhs.value = (*p_++).AsMidiMessage();
348
ReceivedMessageArgumentStream& operator>>( int64& rhs )
351
throw MissingArgumentException();
353
rhs = (*p_++).AsInt64();
357
ReceivedMessageArgumentStream& operator>>( TimeTag& rhs )
360
throw MissingArgumentException();
362
rhs.value = (*p_++).AsTimeTag();
366
ReceivedMessageArgumentStream& operator>>( double& rhs )
369
throw MissingArgumentException();
371
rhs = (*p_++).AsDouble();
375
ReceivedMessageArgumentStream& operator>>( Blob& rhs )
378
throw MissingArgumentException();
380
(*p_++).AsBlob( rhs.data, rhs.size );
384
ReceivedMessageArgumentStream& operator>>( const char*& rhs )
387
throw MissingArgumentException();
389
rhs = (*p_++).AsString();
393
ReceivedMessageArgumentStream& operator>>( Symbol& rhs )
396
throw MissingArgumentException();
398
rhs.value = (*p_++).AsSymbol();
402
ReceivedMessageArgumentStream& operator>>( MessageTerminator& )
405
throw ExcessArgumentException();
412
class ReceivedMessage{
413
void Init( const char *bundle, unsigned long size );
415
explicit ReceivedMessage( const ReceivedPacket& packet );
416
explicit ReceivedMessage( const ReceivedBundleElement& bundleElement );
418
const char *AddressPattern() const { return addressPattern_; }
420
// Support for non-standad SuperCollider integer address patterns:
421
bool AddressPatternIsUInt32() const;
422
uint32 AddressPatternAsUInt32() const;
424
unsigned long ArgumentCount() const { return static_cast<unsigned long>(typeTagsEnd_ - typeTagsBegin_); }
426
const char *TypeTags() const { return typeTagsBegin_; }
429
typedef ReceivedMessageArgumentIterator const_iterator;
431
ReceivedMessageArgumentIterator ArgumentsBegin() const
433
return ReceivedMessageArgumentIterator( typeTagsBegin_, arguments_ );
436
ReceivedMessageArgumentIterator ArgumentsEnd() const
438
return ReceivedMessageArgumentIterator( typeTagsEnd_, 0 );
441
ReceivedMessageArgumentStream ArgumentStream() const
443
return ReceivedMessageArgumentStream( ArgumentsBegin(), ArgumentsEnd() );
447
const char *addressPattern_;
448
const char *typeTagsBegin_;
449
const char *typeTagsEnd_;
450
const char *arguments_;
454
class ReceivedBundle{
455
void Init( const char *message, unsigned long size );
457
explicit ReceivedBundle( const ReceivedPacket& packet );
458
explicit ReceivedBundle( const ReceivedBundleElement& bundleElement );
460
uint64 TimeTag() const;
462
unsigned long ElementCount() const { return elementCount_; }
464
typedef ReceivedBundleElementIterator const_iterator;
466
ReceivedBundleElementIterator ElementsBegin() const
468
return ReceivedBundleElementIterator( timeTag_ + 8 );
471
ReceivedBundleElementIterator ElementsEnd() const
473
return ReceivedBundleElementIterator( end_ );
477
const char *timeTag_;
479
unsigned long elementCount_;
486
#endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */