Merge branch 'master' of https://scm.cri.ensmp.fr/git/Faustine
[Faustine.git] / interpretor / faust-0.9.47mr3 / architecture / osclib / oscpack / osc / OscReceivedElements.h
1 /*
2 oscpack -- Open Sound Control packet manipulation library
3 http://www.audiomulch.com/~rossb/oscpack
4
5 Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
6
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:
14
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
17
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.
21
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.
29 */
30 #ifndef INCLUDED_OSCRECEIVEDELEMENTS_H
31 #define INCLUDED_OSCRECEIVEDELEMENTS_H
32
33 #include "OscTypes.h"
34 #include "OscException.h"
35
36
37 namespace osc{
38
39
40 class MalformedMessageException : public Exception{
41 public:
42 MalformedMessageException( const char *w="malformed message" )
43 : Exception( w ) {}
44 };
45
46 class MalformedBundleException : public Exception{
47 public:
48 MalformedBundleException( const char *w="malformed bundle" )
49 : Exception( w ) {}
50 };
51
52 class WrongArgumentTypeException : public Exception{
53 public:
54 WrongArgumentTypeException( const char *w="wrong argument type" )
55 : Exception( w ) {}
56 };
57
58 class MissingArgumentException : public Exception{
59 public:
60 MissingArgumentException( const char *w="missing argument" )
61 : Exception( w ) {}
62 };
63
64 class ExcessArgumentException : public Exception{
65 public:
66 ExcessArgumentException( const char *w="too many arguments" )
67 : Exception( w ) {}
68 };
69
70
71 class ReceivedPacket{
72 public:
73 ReceivedPacket( const char *contents, int32 size )
74 : contents_( contents )
75 , size_( size ) {}
76
77 bool IsMessage() const { return !IsBundle(); }
78 bool IsBundle() const;
79
80 int32 Size() const { return size_; }
81 const char *Contents() const { return contents_; }
82
83 private:
84 const char *contents_;
85 int32 size_;
86 };
87
88
89 class ReceivedBundleElement{
90 public:
91 ReceivedBundleElement( const char *size )
92 : size_( size ) {}
93
94 friend class ReceivedBundleElementIterator;
95
96 bool IsMessage() const { return !IsBundle(); }
97 bool IsBundle() const;
98
99 int32 Size() const;
100 const char *Contents() const { return size_ + 4; }
101
102 private:
103 const char *size_;
104 };
105
106
107 class ReceivedBundleElementIterator{
108 public:
109 ReceivedBundleElementIterator( const char *sizePtr )
110 : value_( sizePtr ) {}
111
112 ReceivedBundleElementIterator operator++()
113 {
114 Advance();
115 return *this;
116 }
117
118 ReceivedBundleElementIterator operator++(int)
119 {
120 ReceivedBundleElementIterator old( *this );
121 Advance();
122 return old;
123 }
124
125 const ReceivedBundleElement& operator*() const { return value_; }
126
127 const ReceivedBundleElement* operator->() const { return &value_; }
128
129 friend bool operator==(const ReceivedBundleElementIterator& lhs,
130 const ReceivedBundleElementIterator& rhs );
131
132 private:
133 ReceivedBundleElement value_;
134
135 void Advance() { value_.size_ = value_.Contents() + value_.Size(); }
136
137 bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const
138 {
139 return value_.size_ == rhs.value_.size_;
140 }
141 };
142
143 inline bool operator==(const ReceivedBundleElementIterator& lhs,
144 const ReceivedBundleElementIterator& rhs )
145 {
146 return lhs.IsEqualTo( rhs );
147 }
148
149 inline bool operator!=(const ReceivedBundleElementIterator& lhs,
150 const ReceivedBundleElementIterator& rhs )
151 {
152 return !( lhs == rhs );
153 }
154
155
156 class ReceivedMessageArgument{
157 public:
158 ReceivedMessageArgument( const char *typeTag, const char *argument )
159 : typeTag_( typeTag )
160 , argument_( argument ) {}
161
162 friend class ReceivedMessageArgumentIterator;
163
164 const char TypeTag() const { return *typeTag_; }
165
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.
169
170 bool IsBool() const
171 { return *typeTag_ == TRUE_TYPE_TAG || *typeTag_ == FALSE_TYPE_TAG; }
172 bool AsBool() const;
173 bool AsBoolUnchecked() const;
174
175 bool IsNil() const { return *typeTag_ == NIL_TYPE_TAG; }
176 bool IsInfinitum() const { return *typeTag_ == INFINITUM_TYPE_TAG; }
177
178 bool IsInt32() const { return *typeTag_ == INT32_TYPE_TAG; }
179 int32 AsInt32() const;
180 int32 AsInt32Unchecked() const;
181
182 bool IsFloat() const { return *typeTag_ == FLOAT_TYPE_TAG; }
183 float AsFloat() const;
184 float AsFloatUnchecked() const;
185
186 bool IsChar() const { return *typeTag_ == CHAR_TYPE_TAG; }
187 char AsChar() const;
188 char AsCharUnchecked() const;
189
190 bool IsRgbaColor() const { return *typeTag_ == RGBA_COLOR_TYPE_TAG; }
191 uint32 AsRgbaColor() const;
192 uint32 AsRgbaColorUnchecked() const;
193
194 bool IsMidiMessage() const { return *typeTag_ == MIDI_MESSAGE_TYPE_TAG; }
195 uint32 AsMidiMessage() const;
196 uint32 AsMidiMessageUnchecked() const;
197
198 bool IsInt64() const { return *typeTag_ == INT64_TYPE_TAG; }
199 int64 AsInt64() const;
200 int64 AsInt64Unchecked() const;
201
202 bool IsTimeTag() const { return *typeTag_ == TIME_TAG_TYPE_TAG; }
203 uint64 AsTimeTag() const;
204 uint64 AsTimeTagUnchecked() const;
205
206 bool IsDouble() const { return *typeTag_ == DOUBLE_TYPE_TAG; }
207 double AsDouble() const;
208 double AsDoubleUnchecked() const;
209
210 bool IsString() const { return *typeTag_ == STRING_TYPE_TAG; }
211 const char* AsString() const;
212 const char* AsStringUnchecked() const { return argument_; }
213
214 bool IsSymbol() const { return *typeTag_ == SYMBOL_TYPE_TAG; }
215 const char* AsSymbol() const;
216 const char* AsSymbolUnchecked() const { return argument_; }
217
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;
221
222 private:
223 const char *typeTag_;
224 const char *argument_;
225 };
226
227
228 class ReceivedMessageArgumentIterator{
229 public:
230 ReceivedMessageArgumentIterator( const char *typeTags, const char *arguments )
231 : value_( typeTags, arguments ) {}
232
233 ReceivedMessageArgumentIterator operator++()
234 {
235 Advance();
236 return *this;
237 }
238
239 ReceivedMessageArgumentIterator operator++(int)
240 {
241 ReceivedMessageArgumentIterator old( *this );
242 Advance();
243 return old;
244 }
245
246 const ReceivedMessageArgument& operator*() const { return value_; }
247
248 const ReceivedMessageArgument* operator->() const { return &value_; }
249
250 friend bool operator==(const ReceivedMessageArgumentIterator& lhs,
251 const ReceivedMessageArgumentIterator& rhs );
252
253 private:
254 ReceivedMessageArgument value_;
255
256 void Advance();
257
258 bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const
259 {
260 return value_.typeTag_ == rhs.value_.typeTag_;
261 }
262 };
263
264 inline bool operator==(const ReceivedMessageArgumentIterator& lhs,
265 const ReceivedMessageArgumentIterator& rhs )
266 {
267 return lhs.IsEqualTo( rhs );
268 }
269
270 inline bool operator!=(const ReceivedMessageArgumentIterator& lhs,
271 const ReceivedMessageArgumentIterator& rhs )
272 {
273 return !( lhs == rhs );
274 }
275
276
277 class ReceivedMessageArgumentStream{
278 friend class ReceivedMessage;
279 ReceivedMessageArgumentStream( const ReceivedMessageArgumentIterator& begin,
280 const ReceivedMessageArgumentIterator& end )
281 : p_( begin )
282 , end_( end ) {}
283
284 ReceivedMessageArgumentIterator p_, end_;
285
286 public:
287
288 // end of stream
289 bool Eos() const { return p_ == end_; }
290
291 ReceivedMessageArgumentStream& operator>>( bool& rhs )
292 {
293 if( Eos() )
294 throw MissingArgumentException();
295
296 rhs = (*p_++).AsBool();
297 return *this;
298 }
299
300 // not sure if it would be useful to stream Nil and Infinitum
301 // for now it's not possible
302
303 ReceivedMessageArgumentStream& operator>>( int32& rhs )
304 {
305 if( Eos() )
306 throw MissingArgumentException();
307
308 rhs = (*p_++).AsInt32();
309 return *this;
310 }
311
312 ReceivedMessageArgumentStream& operator>>( float& rhs )
313 {
314 if( Eos() )
315 throw MissingArgumentException();
316
317 rhs = (*p_++).AsFloat();
318 return *this;
319 }
320
321 ReceivedMessageArgumentStream& operator>>( char& rhs )
322 {
323 if( Eos() )
324 throw MissingArgumentException();
325
326 rhs = (*p_++).AsChar();
327 return *this;
328 }
329
330 ReceivedMessageArgumentStream& operator>>( RgbaColor& rhs )
331 {
332 if( Eos() )
333 throw MissingArgumentException();
334
335 rhs.value = (*p_++).AsRgbaColor();
336 return *this;
337 }
338
339 ReceivedMessageArgumentStream& operator>>( MidiMessage& rhs )
340 {
341 if( Eos() )
342 throw MissingArgumentException();
343
344 rhs.value = (*p_++).AsMidiMessage();
345 return *this;
346 }
347
348 ReceivedMessageArgumentStream& operator>>( int64& rhs )
349 {
350 if( Eos() )
351 throw MissingArgumentException();
352
353 rhs = (*p_++).AsInt64();
354 return *this;
355 }
356
357 ReceivedMessageArgumentStream& operator>>( TimeTag& rhs )
358 {
359 if( Eos() )
360 throw MissingArgumentException();
361
362 rhs.value = (*p_++).AsTimeTag();
363 return *this;
364 }
365
366 ReceivedMessageArgumentStream& operator>>( double& rhs )
367 {
368 if( Eos() )
369 throw MissingArgumentException();
370
371 rhs = (*p_++).AsDouble();
372 return *this;
373 }
374
375 ReceivedMessageArgumentStream& operator>>( Blob& rhs )
376 {
377 if( Eos() )
378 throw MissingArgumentException();
379
380 (*p_++).AsBlob( rhs.data, rhs.size );
381 return *this;
382 }
383
384 ReceivedMessageArgumentStream& operator>>( const char*& rhs )
385 {
386 if( Eos() )
387 throw MissingArgumentException();
388
389 rhs = (*p_++).AsString();
390 return *this;
391 }
392
393 ReceivedMessageArgumentStream& operator>>( Symbol& rhs )
394 {
395 if( Eos() )
396 throw MissingArgumentException();
397
398 rhs.value = (*p_++).AsSymbol();
399 return *this;
400 }
401
402 ReceivedMessageArgumentStream& operator>>( MessageTerminator& )
403 {
404 if( !Eos() )
405 throw ExcessArgumentException();
406
407 return *this;
408 }
409 };
410
411
412 class ReceivedMessage{
413 void Init( const char *bundle, unsigned long size );
414 public:
415 explicit ReceivedMessage( const ReceivedPacket& packet );
416 explicit ReceivedMessage( const ReceivedBundleElement& bundleElement );
417
418 const char *AddressPattern() const { return addressPattern_; }
419
420 // Support for non-standad SuperCollider integer address patterns:
421 bool AddressPatternIsUInt32() const;
422 uint32 AddressPatternAsUInt32() const;
423
424 unsigned long ArgumentCount() const { return static_cast<unsigned long>(typeTagsEnd_ - typeTagsBegin_); }
425
426 const char *TypeTags() const { return typeTagsBegin_; }
427
428
429 typedef ReceivedMessageArgumentIterator const_iterator;
430
431 ReceivedMessageArgumentIterator ArgumentsBegin() const
432 {
433 return ReceivedMessageArgumentIterator( typeTagsBegin_, arguments_ );
434 }
435
436 ReceivedMessageArgumentIterator ArgumentsEnd() const
437 {
438 return ReceivedMessageArgumentIterator( typeTagsEnd_, 0 );
439 }
440
441 ReceivedMessageArgumentStream ArgumentStream() const
442 {
443 return ReceivedMessageArgumentStream( ArgumentsBegin(), ArgumentsEnd() );
444 }
445
446 private:
447 const char *addressPattern_;
448 const char *typeTagsBegin_;
449 const char *typeTagsEnd_;
450 const char *arguments_;
451 };
452
453
454 class ReceivedBundle{
455 void Init( const char *message, unsigned long size );
456 public:
457 explicit ReceivedBundle( const ReceivedPacket& packet );
458 explicit ReceivedBundle( const ReceivedBundleElement& bundleElement );
459
460 uint64 TimeTag() const;
461
462 unsigned long ElementCount() const { return elementCount_; }
463
464 typedef ReceivedBundleElementIterator const_iterator;
465
466 ReceivedBundleElementIterator ElementsBegin() const
467 {
468 return ReceivedBundleElementIterator( timeTag_ + 8 );
469 }
470
471 ReceivedBundleElementIterator ElementsEnd() const
472 {
473 return ReceivedBundleElementIterator( end_ );
474 }
475
476 private:
477 const char *timeTag_;
478 const char *end_;
479 unsigned long elementCount_;
480 };
481
482
483 } // namespace osc
484
485
486 #endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */