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 #include "OscUnitTests.h"
36 #include "osc/OscReceivedElements.h"
37 #include "osc/OscPrintReceivedElements.h"
38 #include "osc/OscOutboundPacketStream.h"
43 static int passCount_
=0, failCount_
=0;
45 void PrintTestSummary()
47 std::cout
<< (passCount_
+failCount_
) << " tests run, " << passCount_
<< " passed, " << failCount_
<< " failed.\n";
50 void pass_equality( const char *slhs
, const char *srhs
, const char *file
, int line
)
53 std::cout
<< file
<< "(" << line
<< "): PASSED : " << slhs
<< " == " << srhs
<< "\n";
56 void fail_equality( const char *slhs
, const char *srhs
, const char *file
, int line
)
59 std::cout
<< file
<< "(" << line
<< "): FAILED : " << slhs
<< " != " << srhs
<< "\n";
63 void assertEqual_( const T
& lhs
, const T
& rhs
, const char *slhs
, const char *srhs
, const char *file
, int line
)
66 pass_equality( slhs
, srhs
, file
, line
);
68 fail_equality( slhs
, srhs
, file
, line
);
72 void assertEqual_( const T
* lhs
, const T
* rhs
, const char *slhs
, const char *srhs
, const char *file
, int line
)
75 pass_equality( slhs
, srhs
, file
, line
);
77 fail_equality( slhs
, srhs
, file
, line
);
81 void assertEqual_( const char* lhs
, const char* rhs
, const char *slhs
, const char *srhs
, const char *file
, int line
)
83 if( strcmp( lhs
, rhs
) == 0 )
84 pass_equality( slhs
, srhs
, file
, line
);
86 fail_equality( slhs
, srhs
, file
, line
);
90 #define assertEqual( a, b ) assertEqual_( (a), (b), #a, #b, __FILE__, __LINE__ )
92 //---------------------------------------------------------------------------
93 char * AllocateAligned4( unsigned long size
)
95 char *s
= new char[ size
+ 4 ]; //allocate on stack to get 4 byte alignment
96 return (char*)((long)(s
-1) & (~0x03L
)) + 4;
99 // allocate a 4 byte aligned copy of s
100 char * NewMessageBuffer( const char *s
, unsigned long length
)
102 char *p
= AllocateAligned4( length
);
103 memcpy( p
, s
, length
);
109 const char s
[] = "/test\0\0\0,fiT\0\0\0\0\0\0\0\0\0\0\0A";
110 char *buffer
= NewMessageBuffer( s
, sizeof(s
)-1 );
112 // test argument iterator interface
113 bool unexpectedExceptionCaught
= false;
115 ReceivedMessage
m( ReceivedPacket(buffer
, sizeof(s
)-1) );
117 assertEqual( strcmp( m
.AddressPattern(), "/test" ), 0 );
118 assertEqual( strcmp( m
.TypeTags(), "fiT" ), 0 );
120 ReceivedMessage::const_iterator i
= m
.ArgumentsBegin();
124 assertEqual( i
, m
.ArgumentsEnd() );
126 i
= m
.ArgumentsBegin();
127 float f
= (i
++)->AsFloat();
129 int n
= (i
++)->AsInt32();
131 bool b
= (i
++)->AsBool();
134 i
= m
.ArgumentsBegin();
135 bool exceptionThrown
= false;
137 int n
= (i
++)->AsInt32();
139 }catch( Exception
& ){
140 exceptionThrown
= true;
142 assertEqual( exceptionThrown
, true );
144 }catch( Exception
& e
){
145 std::cout
<< "unexpected exception: " << e
.what() << "\n";
146 unexpectedExceptionCaught
= true;
148 assertEqual( unexpectedExceptionCaught
, false );
151 // test argument stream interface
152 unexpectedExceptionCaught
= false;
154 ReceivedMessage
m( ReceivedPacket(buffer
, sizeof(s
)-1) );
155 ReceivedMessageArgumentStream args
= m
.ArgumentStream();
156 assertEqual( args
.Eos(), false );
167 assertEqual( args
.Eos(), true );
169 }catch( Exception
& e
){
170 std::cout
<< "unexpected exception: " << e
.what() << "\n";
171 unexpectedExceptionCaught
= true;
173 assertEqual( unexpectedExceptionCaught
, false );
176 //---------------------------------------------------------------------------
179 #define TEST2_PRINT( ss )\
181 const char s[] = ss;\
182 ReceivedPacket p( NewMessageBuffer( s, sizeof(s)-1 ), sizeof(s)-1 ); \
183 ReceivedMessage m( p );\
184 std::cout << m << "\n";\
189 bool unexpectedExceptionCaught
= false;
192 TEST2_PRINT( "/no_args\0\0\0\0" );
194 // 012301230 1 2 3 01 2 3
195 TEST2_PRINT( "/no_args\0\0\0\0,\0\0\0" );
197 // 01230123 012 3 0 1 2 3
198 TEST2_PRINT( "/an_int\0,i\0\0\0\0\0A" );
199 // 012301230 1 2 3 012 3 0 1 2 3
200 TEST2_PRINT( "/a_float\0\0\0\0,f\0\0\0\0\0\0" );
201 // 0123012301 2 3 012 3 012301230123
202 TEST2_PRINT( "/a_string\0\0\0,s\0\0hello world\0" );
203 // 01230123 012 3 0 1 2 3 0 1 2 3
204 TEST2_PRINT( "/a_blob\0,b\0\0\0\0\0\x4\x0\x1\x2\x3" );
206 // 0123012301 2 3 012 3 0 1 2 3 0 1 2 3
207 TEST2_PRINT( "/an_int64\0\0\0,h\0\0\0\0\0\0\0\0\0\x1" );
208 // 01230123012 3 012 3 0 1 2 3 0 1 2 3
209 TEST2_PRINT( "/a_timetag\0\0,t\0\0\0\0\0\0\0\0\0\x1" );
210 // 0123012301 2 3 012 3 0 1 2 3 0 1 2 3
211 TEST2_PRINT( "/a_double\0\0\0,d\0\0\0\0\0\0\0\0\0\0" );
212 // 0123012301 2 3 012 3 012301230123
213 TEST2_PRINT( "/a_symbol\0\0\0,S\0\0hello world\0" );
214 // 01230123 012 3 0 1 2 3
215 TEST2_PRINT( "/a_char\0,c\0\0\0\0\0A" );
216 // 012301230 1 2 3 012 3 0 1 2 3
217 TEST2_PRINT( "/a_color\0\0\0\0,r\0\0\0\0\0\0" );
218 // 012301230123012 3 012 3 0 1 2 3
219 TEST2_PRINT( "/a_midimessage\0\0,m\0\0\0\0\0\0" );
221 TEST2_PRINT( "/a_bool\0,T\0\0" );
223 TEST2_PRINT( "/a_bool\0,F\0\0" );
225 TEST2_PRINT( "/Nil\0\0\0\0,N\0\0" );
227 TEST2_PRINT( "/Inf\0\0\0\0,I\0\0" );
229 TEST2_PRINT( "/test\0\0\0,fiT\0\0\0\0\0\0\0\0\0\0\0A" );
231 bool exceptionThrown
= false;
233 TEST2_PRINT( "/a_char\0,x\0\0\0\0\0A" ); // unknown type tag 'x'
234 }catch( Exception
& ){
235 exceptionThrown
= true;
237 assertEqual( exceptionThrown
, true );
239 }catch( Exception
& e
){
240 std::cout
<< "unexpected exception: " << e
.what() << "\n";
241 unexpectedExceptionCaught
= true;
243 assertEqual( unexpectedExceptionCaught
, false );
246 //-----------------------------------------------------------------------
248 // pack a message and then unpack it and check that the result is the same
249 // also print each message
250 // repeat the process inside a bundle
252 #define TEST_PACK_UNPACK0( addressPattern, argument, value, recieveGetter ) \
254 memset( buffer, 0x74, bufferSize ); \
255 OutboundPacketStream ps( buffer, bufferSize ); \
256 ps << BeginMessage( addressPattern ) \
259 assertEqual( ps.IsReady(), true );\
260 ReceivedMessage m( ReceivedPacket(ps.Data(), ps.Size()) );\
261 std::cout << m << "\n";\
262 assertEqual( m.ArgumentsBegin()-> recieveGetter () , value );\
265 memset( buffer, 0x74, bufferSize ); \
266 OutboundPacketStream ps( buffer, bufferSize ); \
267 ps << BeginBundle( 1234 ) \
268 << BeginMessage( addressPattern ) \
272 assertEqual( ps.IsReady(), true );\
273 ReceivedBundle b( ReceivedPacket(ps.Data(), ps.Size()) );\
274 ReceivedMessage m( *b.ElementsBegin() );\
275 std::cout << m << "\n";\
276 assertEqual( m.ArgumentsBegin()-> recieveGetter () , value );\
279 #define TEST_PACK_UNPACK( addressPattern, argument, type, recieveGetter ) \
281 memset( buffer, 0x74, bufferSize ); \
282 OutboundPacketStream ps( buffer, bufferSize ); \
283 ps << BeginMessage( addressPattern ) \
286 assertEqual( ps.IsReady(), true );\
287 ReceivedMessage m( ReceivedPacket(ps.Data(), ps.Size()) );\
288 std::cout << m << "\n";\
289 assertEqual( m.ArgumentsBegin()-> recieveGetter () , ( type ) argument );\
292 memset( buffer, 0x74, bufferSize ); \
293 OutboundPacketStream ps( buffer, bufferSize ); \
294 ps << BeginBundle( 1234 ) \
295 << BeginMessage( addressPattern ) \
299 assertEqual( ps.IsReady(), true );\
300 ReceivedBundle b( ReceivedPacket(ps.Data(), ps.Size()) );\
301 ReceivedMessage m( *b.ElementsBegin() );\
302 std::cout << m << "\n";\
303 assertEqual( m.ArgumentsBegin()-> recieveGetter () , ( type ) argument );\
308 int bufferSize
= 1000;
309 char *buffer
= AllocateAligned4( bufferSize
);
311 // single message tests
314 memset( buffer
, 0x74, bufferSize
);
315 OutboundPacketStream
ps( buffer
, bufferSize
);
316 ps
<< BeginMessage( "/no_arguments" )
318 assertEqual( ps
.IsReady(), true );
319 ReceivedMessage
m( ReceivedPacket(ps
.Data(), ps
.Size()) );
320 std::cout
<< m
<< "\n";\
323 TEST_PACK_UNPACK( "/a_bool", true, bool, AsBool
);
324 TEST_PACK_UNPACK( "/a_bool", false, bool, AsBool
);
325 TEST_PACK_UNPACK( "/a_bool", (bool)1, bool, AsBool
);
327 TEST_PACK_UNPACK0( "/nil", Nil
, true, IsNil
);
328 TEST_PACK_UNPACK0( "/inf", Infinitum
, true, IsInfinitum
);
330 TEST_PACK_UNPACK( "/an_int", (int32
)1234, int32
, AsInt32
);
332 TEST_PACK_UNPACK( "/a_float", 3.1415926f
, float, AsFloat
);
334 TEST_PACK_UNPACK( "/a_char", 'c', char, AsChar
);
336 TEST_PACK_UNPACK( "/an_rgba_color", RgbaColor(0x22334455), uint32
, AsRgbaColor
);
338 TEST_PACK_UNPACK( "/a_midi_message", MidiMessage(0x7F), uint32
, AsMidiMessage
);
340 TEST_PACK_UNPACK( "/an_int64", (int64
)(0xFFFFFFFF), int64
, AsInt64
);
342 TEST_PACK_UNPACK( "/a_time_tag", TimeTag(0xFFFFFFFF), uint64
, AsTimeTag
);
344 TEST_PACK_UNPACK( "/a_double", (double)3.1415926, double, AsDouble
);
348 char blobData
[] = "abcd";
349 memset( buffer
, 0x74, bufferSize
);
350 OutboundPacketStream
ps( buffer
, bufferSize
);
351 ps
<< BeginMessage( "/a_blob" )
352 << Blob( blobData
, 4 )
354 assertEqual( ps
.IsReady(), true );
355 ReceivedMessage
m( ReceivedPacket(ps
.Data(), ps
.Size()) );
356 std::cout
<< m
<< "\n";
360 m
.ArgumentsBegin()->AsBlob( value
, size
);
361 assertEqual( size
, (unsigned long)4 );
362 assertEqual( (memcmp( value
, blobData
, 4 ) == 0), true );
366 TEST_PACK_UNPACK( "/a_string", "hello world", const char*, AsString
);
368 TEST_PACK_UNPACK( "/a_symbol", Symbol("foobar"), const char*, AsSymbol
);
371 // nested bundles, and multiple messages in bundles...
374 memset( buffer
, 0x74, bufferSize
);
375 OutboundPacketStream
ps( buffer
, bufferSize
);
377 << BeginMessage( "/message_one" ) << 1 << 2 << 3 << 4 << EndMessage
378 << BeginMessage( "/message_two" ) << 1 << 2 << 3 << 4 << EndMessage
379 << BeginMessage( "/message_three" ) << 1 << 2 << 3 << 4 << EndMessage
380 << BeginMessage( "/message_four" ) << 1 << 2 << 3 << 4 << EndMessage
382 assertEqual( ps
.IsReady(), true );
383 ReceivedBundle
b( ReceivedPacket(ps
.Data(), ps
.Size()) );
384 std::cout
<< b
<< "\n";
400 #ifndef NO_OSC_TEST_MAIN
402 int main(int argc
, char* argv
[])