1 /* |
1 /* |
2 oscpack -- Open Sound Control packet manipulation library |
2 oscpack -- Open Sound Control packet manipulation library |
3 http://www.audiomulch.com/~rossb/oscpack |
3 http://www.audiomulch.com/~rossb/oscpack |
4 |
4 |
5 Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com> |
5 Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com> |
6 |
6 |
7 Permission is hereby granted, free of charge, to any person obtaining |
7 Permission is hereby granted, free of charge, to any person obtaining |
8 a copy of this software and associated documentation files |
8 a copy of this software and associated documentation files |
9 (the "Software"), to deal in the Software without restriction, |
9 (the "Software"), to deal in the Software without restriction, |
10 including without limitation the rights to use, copy, modify, merge, |
10 including without limitation the rights to use, copy, modify, merge, |
11 publish, distribute, sublicense, and/or sell copies of the Software, |
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, |
12 and to permit persons to whom the Software is furnished to do so, |
13 subject to the following conditions: |
13 subject to the following conditions: |
14 |
14 |
15 The above copyright notice and this permission notice shall be |
15 The above copyright notice and this permission notice shall be |
16 included in all copies or substantial portions of the Software. |
16 included in all copies or substantial portions of the Software. |
17 |
17 |
18 Any person wishing to distribute modifications to the Software is |
18 Any person wishing to distribute modifications to the Software is |
19 requested to send the modifications to the original developer so that |
19 requested to send the modifications to the original developer so that |
20 they can be incorporated into the canonical version. |
20 they can be incorporated into the canonical version. |
21 |
21 |
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
25 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR |
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 |
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
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. |
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
29 */ |
29 */ |
30 #ifndef INCLUDED_OSCRECEIVEDELEMENTS_H |
30 #ifndef INCLUDED_OSCRECEIVEDELEMENTS_H |
31 #define INCLUDED_OSCRECEIVEDELEMENTS_H |
31 #define INCLUDED_OSCRECEIVEDELEMENTS_H |
32 |
32 |
33 #include "OscTypes.h" |
33 #include "OscTypes.h" |
104 }; |
104 }; |
105 |
105 |
106 |
106 |
107 class ReceivedBundleElementIterator{ |
107 class ReceivedBundleElementIterator{ |
108 public: |
108 public: |
109 ReceivedBundleElementIterator( const char *sizePtr ) |
109 ReceivedBundleElementIterator( const char *sizePtr ) |
110 : value_( sizePtr ) {} |
110 : value_( sizePtr ) {} |
111 |
111 |
112 ReceivedBundleElementIterator operator++() |
112 ReceivedBundleElementIterator operator++() |
113 { |
113 { |
114 Advance(); |
114 Advance(); |
115 return *this; |
115 return *this; |
116 } |
116 } |
117 |
117 |
118 ReceivedBundleElementIterator operator++(int) |
118 ReceivedBundleElementIterator operator++(int) |
119 { |
119 { |
120 ReceivedBundleElementIterator old( *this ); |
120 ReceivedBundleElementIterator old( *this ); |
121 Advance(); |
121 Advance(); |
122 return old; |
122 return old; |
123 } |
123 } |
124 |
124 |
125 const ReceivedBundleElement& operator*() const { return value_; } |
125 const ReceivedBundleElement& operator*() const { return value_; } |
126 |
126 |
127 const ReceivedBundleElement* operator->() const { return &value_; } |
127 const ReceivedBundleElement* operator->() const { return &value_; } |
128 |
128 |
129 friend bool operator==(const ReceivedBundleElementIterator& lhs, |
129 friend bool operator==(const ReceivedBundleElementIterator& lhs, |
130 const ReceivedBundleElementIterator& rhs ); |
130 const ReceivedBundleElementIterator& rhs ); |
131 |
131 |
132 private: |
132 private: |
133 ReceivedBundleElement value_; |
133 ReceivedBundleElement value_; |
134 |
134 |
135 void Advance() { value_.size_ = value_.Contents() + value_.Size(); } |
135 void Advance() { value_.size_ = value_.Contents() + value_.Size(); } |
136 |
136 |
137 bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const |
137 bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const |
138 { |
138 { |
139 return value_.size_ == rhs.value_.size_; |
139 return value_.size_ == rhs.value_.size_; |
140 } |
140 } |
141 }; |
141 }; |
142 |
142 |
143 inline bool operator==(const ReceivedBundleElementIterator& lhs, |
143 inline bool operator==(const ReceivedBundleElementIterator& lhs, |
144 const ReceivedBundleElementIterator& rhs ) |
144 const ReceivedBundleElementIterator& rhs ) |
145 { |
145 { |
146 return lhs.IsEqualTo( rhs ); |
146 return lhs.IsEqualTo( rhs ); |
147 } |
147 } |
148 |
148 |
149 inline bool operator!=(const ReceivedBundleElementIterator& lhs, |
149 inline bool operator!=(const ReceivedBundleElementIterator& lhs, |
150 const ReceivedBundleElementIterator& rhs ) |
150 const ReceivedBundleElementIterator& rhs ) |
151 { |
151 { |
152 return !( lhs == rhs ); |
152 return !( lhs == rhs ); |
153 } |
153 } |
154 |
154 |
155 |
155 |
156 class ReceivedMessageArgument{ |
156 class ReceivedMessageArgument{ |
157 public: |
157 public: |
158 ReceivedMessageArgument( const char *typeTag, const char *argument ) |
158 ReceivedMessageArgument( const char *typeTag, const char *argument ) |
159 : typeTag_( typeTag ) |
159 : typeTag_( typeTag ) |
160 , argument_( argument ) {} |
160 , argument_( argument ) {} |
161 |
161 |
162 friend class ReceivedMessageArgumentIterator; |
162 friend class ReceivedMessageArgumentIterator; |
163 |
163 |
164 const char TypeTag() const { return *typeTag_; } |
164 const char TypeTag() const { return *typeTag_; } |
165 |
165 |
166 // the unchecked methods below don't check whether the argument actually |
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 |
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. |
168 // checked the type tag or the associated IsType() method. |
169 |
169 |
218 bool IsBlob() const { return *typeTag_ == BLOB_TYPE_TAG; } |
218 bool IsBlob() const { return *typeTag_ == BLOB_TYPE_TAG; } |
219 void AsBlob( const void*& data, unsigned long& size ) const; |
219 void AsBlob( const void*& data, unsigned long& size ) const; |
220 void AsBlobUnchecked( const void*& data, unsigned long& size ) const; |
220 void AsBlobUnchecked( const void*& data, unsigned long& size ) const; |
221 |
221 |
222 private: |
222 private: |
223 const char *typeTag_; |
223 const char *typeTag_; |
224 const char *argument_; |
224 const char *argument_; |
225 }; |
225 }; |
226 |
226 |
227 |
227 |
228 class ReceivedMessageArgumentIterator{ |
228 class ReceivedMessageArgumentIterator{ |
229 public: |
229 public: |
230 ReceivedMessageArgumentIterator( const char *typeTags, const char *arguments ) |
230 ReceivedMessageArgumentIterator( const char *typeTags, const char *arguments ) |
231 : value_( typeTags, arguments ) {} |
231 : value_( typeTags, arguments ) {} |
232 |
232 |
233 ReceivedMessageArgumentIterator operator++() |
233 ReceivedMessageArgumentIterator operator++() |
234 { |
234 { |
235 Advance(); |
235 Advance(); |
236 return *this; |
236 return *this; |
237 } |
237 } |
238 |
238 |
239 ReceivedMessageArgumentIterator operator++(int) |
239 ReceivedMessageArgumentIterator operator++(int) |
240 { |
240 { |
241 ReceivedMessageArgumentIterator old( *this ); |
241 ReceivedMessageArgumentIterator old( *this ); |
242 Advance(); |
242 Advance(); |
243 return old; |
243 return old; |
244 } |
244 } |
245 |
245 |
246 const ReceivedMessageArgument& operator*() const { return value_; } |
246 const ReceivedMessageArgument& operator*() const { return value_; } |
247 |
247 |
248 const ReceivedMessageArgument* operator->() const { return &value_; } |
248 const ReceivedMessageArgument* operator->() const { return &value_; } |
249 |
249 |
250 friend bool operator==(const ReceivedMessageArgumentIterator& lhs, |
250 friend bool operator==(const ReceivedMessageArgumentIterator& lhs, |
251 const ReceivedMessageArgumentIterator& rhs ); |
251 const ReceivedMessageArgumentIterator& rhs ); |
252 |
252 |
253 private: |
253 private: |
254 ReceivedMessageArgument value_; |
254 ReceivedMessageArgument value_; |
255 |
255 |
256 void Advance(); |
256 void Advance(); |
257 |
257 |
258 bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const |
258 bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const |
259 { |
259 { |
260 return value_.typeTag_ == rhs.value_.typeTag_; |
260 return value_.typeTag_ == rhs.value_.typeTag_; |
261 } |
261 } |
262 }; |
262 }; |
263 |
263 |
264 inline bool operator==(const ReceivedMessageArgumentIterator& lhs, |
264 inline bool operator==(const ReceivedMessageArgumentIterator& lhs, |
265 const ReceivedMessageArgumentIterator& rhs ) |
265 const ReceivedMessageArgumentIterator& rhs ) |
266 { |
266 { |
267 return lhs.IsEqualTo( rhs ); |
267 return lhs.IsEqualTo( rhs ); |
268 } |
268 } |
269 |
269 |
270 inline bool operator!=(const ReceivedMessageArgumentIterator& lhs, |
270 inline bool operator!=(const ReceivedMessageArgumentIterator& lhs, |
271 const ReceivedMessageArgumentIterator& rhs ) |
271 const ReceivedMessageArgumentIterator& rhs ) |
272 { |
272 { |
273 return !( lhs == rhs ); |
273 return !( lhs == rhs ); |
274 } |
274 } |
275 |
275 |
276 |
276 |
277 class ReceivedMessageArgumentStream{ |
277 class ReceivedMessageArgumentStream{ |
278 friend class ReceivedMessage; |
278 friend class ReceivedMessage; |
413 void Init( const char *bundle, unsigned long size ); |
413 void Init( const char *bundle, unsigned long size ); |
414 public: |
414 public: |
415 explicit ReceivedMessage( const ReceivedPacket& packet ); |
415 explicit ReceivedMessage( const ReceivedPacket& packet ); |
416 explicit ReceivedMessage( const ReceivedBundleElement& bundleElement ); |
416 explicit ReceivedMessage( const ReceivedBundleElement& bundleElement ); |
417 |
417 |
418 const char *AddressPattern() const { return addressPattern_; } |
418 const char *AddressPattern() const { return addressPattern_; } |
419 |
419 |
420 // Support for non-standad SuperCollider integer address patterns: |
420 // Support for non-standad SuperCollider integer address patterns: |
421 bool AddressPatternIsUInt32() const; |
421 bool AddressPatternIsUInt32() const; |
422 uint32 AddressPatternAsUInt32() const; |
422 uint32 AddressPatternAsUInt32() const; |
423 |
423 |
424 unsigned long ArgumentCount() const { return static_cast<unsigned long>(typeTagsEnd_ - typeTagsBegin_); } |
424 unsigned long ArgumentCount() const { return static_cast<unsigned long>(typeTagsEnd_ - typeTagsBegin_); } |
425 |
425 |
426 const char *TypeTags() const { return typeTagsBegin_; } |
426 const char *TypeTags() const { return typeTagsBegin_; } |
427 |
427 |
428 |
428 |
429 typedef ReceivedMessageArgumentIterator const_iterator; |
429 typedef ReceivedMessageArgumentIterator const_iterator; |
430 |
430 |
431 ReceivedMessageArgumentIterator ArgumentsBegin() const |
431 ReceivedMessageArgumentIterator ArgumentsBegin() const |
432 { |
432 { |
433 return ReceivedMessageArgumentIterator( typeTagsBegin_, arguments_ ); |
433 return ReceivedMessageArgumentIterator( typeTagsBegin_, arguments_ ); |
434 } |
434 } |
435 |
435 |
436 ReceivedMessageArgumentIterator ArgumentsEnd() const |
436 ReceivedMessageArgumentIterator ArgumentsEnd() const |
437 { |
437 { |
438 return ReceivedMessageArgumentIterator( typeTagsEnd_, 0 ); |
438 return ReceivedMessageArgumentIterator( typeTagsEnd_, 0 ); |
439 } |
439 } |
440 |
440 |
441 ReceivedMessageArgumentStream ArgumentStream() const |
441 ReceivedMessageArgumentStream ArgumentStream() const |
442 { |
442 { |
443 return ReceivedMessageArgumentStream( ArgumentsBegin(), ArgumentsEnd() ); |
443 return ReceivedMessageArgumentStream( ArgumentsBegin(), ArgumentsEnd() ); |
444 } |
444 } |
445 |
445 |
446 private: |
446 private: |
447 const char *addressPattern_; |
447 const char *addressPattern_; |
448 const char *typeTagsBegin_; |
448 const char *typeTagsBegin_; |
449 const char *typeTagsEnd_; |
449 const char *typeTagsEnd_; |
450 const char *arguments_; |
450 const char *arguments_; |
451 }; |
451 }; |
452 |
452 |
453 |
453 |
454 class ReceivedBundle{ |
454 class ReceivedBundle{ |