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 */
|