cmake build system: visiblity support for clang
[supercollider.git] / external_libraries / oscpack / osc / OscReceivedElements.h
blob20298fffb94058aa48cc650054d46f2a1943df1b
1 /*
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
33 #include <cstddef>
35 #include "OscTypes.h"
36 #include "OscException.h"
39 namespace osc{
42 class MalformedMessageException : public Exception{
43 public:
44 MalformedMessageException( const char *w="malformed message" )
45 : Exception( w ) {}
48 class MalformedBundleException : public Exception{
49 public:
50 MalformedBundleException( const char *w="malformed bundle" )
51 : Exception( w ) {}
54 class WrongArgumentTypeException : public Exception{
55 public:
56 WrongArgumentTypeException( const char *w="wrong argument type" )
57 : Exception( w ) {}
60 class MissingArgumentException : public Exception{
61 public:
62 MissingArgumentException( const char *w="missing argument" )
63 : Exception( w ) {}
66 class ExcessArgumentException : public Exception{
67 public:
68 ExcessArgumentException( const char *w="too many arguments" )
69 : Exception( w ) {}
73 class ReceivedPacket{
74 public:
75 ReceivedPacket( const char *contents, int32 size )
76 : contents_( contents )
77 , size_( size ) {}
79 bool IsMessage() const { return !IsBundle(); }
80 bool IsBundle() const;
82 int32 Size() const { return size_; }
83 const char *Contents() const { return contents_; }
85 private:
86 const char *contents_;
87 int32 size_;
91 class ReceivedBundleElement{
92 public:
93 ReceivedBundleElement( const char *size )
94 : size_( size ) {}
96 friend class ReceivedBundleElementIterator;
98 bool IsMessage() const { return !IsBundle(); }
99 bool IsBundle() const;
101 int32 Size() const;
102 const char *Contents() const { return size_ + 4; }
104 private:
105 const char *size_;
109 class ReceivedBundleElementIterator{
110 public:
111 ReceivedBundleElementIterator( const char *sizePtr )
112 : value_( sizePtr ) {}
114 ReceivedBundleElementIterator operator++()
116 Advance();
117 return *this;
120 ReceivedBundleElementIterator operator++(int)
122 ReceivedBundleElementIterator old( *this );
123 Advance();
124 return old;
127 const ReceivedBundleElement& operator*() const { return value_; }
129 const ReceivedBundleElement* operator->() const { return &value_; }
131 friend bool operator==(const ReceivedBundleElementIterator& lhs,
132 const ReceivedBundleElementIterator& rhs );
134 private:
135 ReceivedBundleElement value_;
137 void Advance() { value_.size_ = value_.Contents() + value_.Size(); }
139 bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const
141 return value_.size_ == rhs.value_.size_;
145 inline bool operator==(const ReceivedBundleElementIterator& lhs,
146 const ReceivedBundleElementIterator& rhs )
148 return lhs.IsEqualTo( rhs );
151 inline bool operator!=(const ReceivedBundleElementIterator& lhs,
152 const ReceivedBundleElementIterator& rhs )
154 return !( lhs == rhs );
158 class ReceivedMessageArgument{
159 public:
160 ReceivedMessageArgument( const char *typeTag, const char *argument )
161 : typeTag_( typeTag )
162 , argument_( argument ) {}
164 friend class ReceivedMessageArgumentIterator;
166 const char TypeTag() const { return *typeTag_; }
168 // the unchecked methods below don't check whether the argument actually
169 // is of the specified type. they should only be used if you've already
170 // checked the type tag or the associated IsType() method.
172 bool IsBool() const
173 { return *typeTag_ == TRUE_TYPE_TAG || *typeTag_ == FALSE_TYPE_TAG; }
174 bool AsBool() const;
175 bool AsBoolUnchecked() const;
177 bool IsNil() const { return *typeTag_ == NIL_TYPE_TAG; }
178 bool IsInfinitum() const { return *typeTag_ == INFINITUM_TYPE_TAG; }
180 bool IsInt32() const { return *typeTag_ == INT32_TYPE_TAG; }
181 int32 AsInt32() const;
182 int32 AsInt32Unchecked() const;
184 bool IsFloat() const { return *typeTag_ == FLOAT_TYPE_TAG; }
185 float AsFloat() const;
186 float AsFloatUnchecked() const;
188 bool IsChar() const { return *typeTag_ == CHAR_TYPE_TAG; }
189 char AsChar() const;
190 char AsCharUnchecked() const;
192 bool IsRgbaColor() const { return *typeTag_ == RGBA_COLOR_TYPE_TAG; }
193 uint32 AsRgbaColor() const;
194 uint32 AsRgbaColorUnchecked() const;
196 bool IsMidiMessage() const { return *typeTag_ == MIDI_MESSAGE_TYPE_TAG; }
197 uint32 AsMidiMessage() const;
198 uint32 AsMidiMessageUnchecked() const;
200 bool IsInt64() const { return *typeTag_ == INT64_TYPE_TAG; }
201 int64 AsInt64() const;
202 int64 AsInt64Unchecked() const;
204 bool IsTimeTag() const { return *typeTag_ == TIME_TAG_TYPE_TAG; }
205 uint64 AsTimeTag() const;
206 uint64 AsTimeTagUnchecked() const;
208 bool IsDouble() const { return *typeTag_ == DOUBLE_TYPE_TAG; }
209 double AsDouble() const;
210 double AsDoubleUnchecked() const;
212 bool IsString() const { return *typeTag_ == STRING_TYPE_TAG; }
213 const char* AsString() const;
214 const char* AsStringUnchecked() const { return argument_; }
216 bool IsSymbol() const { return *typeTag_ == SYMBOL_TYPE_TAG; }
217 const char* AsSymbol() const;
218 const char* AsSymbolUnchecked() const { return argument_; }
220 bool IsBlob() const { return *typeTag_ == BLOB_TYPE_TAG; }
221 void AsBlob( const void*& data, unsigned long& size ) const;
222 void AsBlobUnchecked( const void*& data, unsigned long& size ) const;
224 bool IsArrayStart() const { return *typeTag_ == ARRAY_START_TYPE_TAG; }
225 bool IsArrayEnd() const { return *typeTag_ == ARRAY_END_TYPE_TAG; }
227 std::size_t ArraySize() const;
229 private:
230 const char *typeTag_;
231 const char *argument_;
235 class ReceivedMessageArgumentIterator{
236 public:
237 ReceivedMessageArgumentIterator( const char *typeTags, const char *arguments )
238 : value_( typeTags, arguments ) {}
240 ReceivedMessageArgumentIterator operator++()
242 Advance();
243 return *this;
246 ReceivedMessageArgumentIterator operator++(int)
248 ReceivedMessageArgumentIterator old( *this );
249 Advance();
250 return old;
253 const ReceivedMessageArgument& operator*() const { return value_; }
255 const ReceivedMessageArgument* operator->() const { return &value_; }
257 friend bool operator==(const ReceivedMessageArgumentIterator& lhs,
258 const ReceivedMessageArgumentIterator& rhs );
260 private:
261 ReceivedMessageArgument value_;
263 void Advance();
265 bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const
267 return value_.typeTag_ == rhs.value_.typeTag_;
271 inline bool operator==(const ReceivedMessageArgumentIterator& lhs,
272 const ReceivedMessageArgumentIterator& rhs )
274 return lhs.IsEqualTo( rhs );
277 inline bool operator!=(const ReceivedMessageArgumentIterator& lhs,
278 const ReceivedMessageArgumentIterator& rhs )
280 return !( lhs == rhs );
284 class ReceivedMessageArgumentStream{
285 friend class ReceivedMessage;
286 ReceivedMessageArgumentStream( const ReceivedMessageArgumentIterator& begin,
287 const ReceivedMessageArgumentIterator& end )
288 : p_( begin )
289 , end_( end ) {}
291 ReceivedMessageArgumentIterator p_, end_;
293 public:
295 // end of stream
296 bool Eos() const { return p_ == end_; }
298 ReceivedMessageArgumentStream& operator>>( bool& rhs )
300 if( Eos() )
301 throw MissingArgumentException();
303 rhs = (*p_++).AsBool();
304 return *this;
307 // not sure if it would be useful to stream Nil and Infinitum
308 // for now it's not possible
309 // same goes for array boundaries
311 ReceivedMessageArgumentStream& operator>>( int32& rhs )
313 if( Eos() )
314 throw MissingArgumentException();
316 rhs = (*p_++).AsInt32();
317 return *this;
320 ReceivedMessageArgumentStream& operator>>( float& rhs )
322 if( Eos() )
323 throw MissingArgumentException();
325 rhs = (*p_++).AsFloat();
326 return *this;
329 ReceivedMessageArgumentStream& operator>>( char& rhs )
331 if( Eos() )
332 throw MissingArgumentException();
334 rhs = (*p_++).AsChar();
335 return *this;
338 ReceivedMessageArgumentStream& operator>>( RgbaColor& rhs )
340 if( Eos() )
341 throw MissingArgumentException();
343 rhs.value = (*p_++).AsRgbaColor();
344 return *this;
347 ReceivedMessageArgumentStream& operator>>( MidiMessage& rhs )
349 if( Eos() )
350 throw MissingArgumentException();
352 rhs.value = (*p_++).AsMidiMessage();
353 return *this;
356 ReceivedMessageArgumentStream& operator>>( int64& rhs )
358 if( Eos() )
359 throw MissingArgumentException();
361 rhs = (*p_++).AsInt64();
362 return *this;
365 ReceivedMessageArgumentStream& operator>>( TimeTag& rhs )
367 if( Eos() )
368 throw MissingArgumentException();
370 rhs.value = (*p_++).AsTimeTag();
371 return *this;
374 ReceivedMessageArgumentStream& operator>>( double& rhs )
376 if( Eos() )
377 throw MissingArgumentException();
379 rhs = (*p_++).AsDouble();
380 return *this;
383 ReceivedMessageArgumentStream& operator>>( Blob& rhs )
385 if( Eos() )
386 throw MissingArgumentException();
388 (*p_++).AsBlob( rhs.data, rhs.size );
389 return *this;
392 ReceivedMessageArgumentStream& operator>>( const char*& rhs )
394 if( Eos() )
395 throw MissingArgumentException();
397 rhs = (*p_++).AsString();
398 return *this;
401 ReceivedMessageArgumentStream& operator>>( Symbol& rhs )
403 if( Eos() )
404 throw MissingArgumentException();
406 rhs.value = (*p_++).AsSymbol();
407 return *this;
410 ReceivedMessageArgumentStream& operator>>( MessageTerminator& rhs )
412 if( !Eos() )
413 throw ExcessArgumentException();
415 return *this;
420 class ReceivedMessage{
421 void Init( const char *bundle, unsigned long size );
422 public:
423 explicit ReceivedMessage( const ReceivedPacket& packet );
424 explicit ReceivedMessage( const ReceivedBundleElement& bundleElement );
426 const char *AddressPattern() const { return addressPattern_; }
428 // Support for non-standad SuperCollider integer address patterns:
429 bool AddressPatternIsUInt32() const;
430 uint32 AddressPatternAsUInt32() const;
432 unsigned long ArgumentCount() const { return static_cast<unsigned long>(typeTagsEnd_ - typeTagsBegin_); }
434 const char *TypeTags() const { return typeTagsBegin_; }
437 typedef ReceivedMessageArgumentIterator const_iterator;
439 ReceivedMessageArgumentIterator ArgumentsBegin() const
441 return ReceivedMessageArgumentIterator( typeTagsBegin_, arguments_ );
444 ReceivedMessageArgumentIterator ArgumentsEnd() const
446 return ReceivedMessageArgumentIterator( typeTagsEnd_, 0 );
449 ReceivedMessageArgumentStream ArgumentStream() const
451 return ReceivedMessageArgumentStream( ArgumentsBegin(), ArgumentsEnd() );
454 private:
455 const char *addressPattern_;
456 const char *typeTagsBegin_;
457 const char *typeTagsEnd_;
458 const char *arguments_;
462 class ReceivedBundle{
463 void Init( const char *message, unsigned long size );
464 public:
465 explicit ReceivedBundle( const ReceivedPacket& packet );
466 explicit ReceivedBundle( const ReceivedBundleElement& bundleElement );
468 uint64 TimeTag() const;
470 unsigned long ElementCount() const { return elementCount_; }
472 typedef ReceivedBundleElementIterator const_iterator;
474 ReceivedBundleElementIterator ElementsBegin() const
476 return ReceivedBundleElementIterator( timeTag_ + 8 );
479 ReceivedBundleElementIterator ElementsEnd() const
481 return ReceivedBundleElementIterator( end_ );
484 private:
485 const char *timeTag_;
486 const char *end_;
487 unsigned long elementCount_;
491 } // namespace osc
494 #endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */