~ubuntu-branches/ubuntu/saucy/faust/saucy

« back to all changes in this revision

Viewing changes to architecture/osclib/oscpack/osc/OscReceivedElements.h

  • Committer: Package Import Robot
  • Author(s): Mario Lang
  • Date: 2012-04-04 13:52:01 UTC
  • mfrom: (1.1.6) (3.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20120404135201-hpsrk87x3hga94tc
Tags: 0.9.46-2
* Fix "ftbfs with GCC-4.7":
  - debian/patches/unistd: Include <unistd.h> where necessary.
    (Closes: #667163)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 */