]> git.sesse.net Git - casparcg/blob - protocol/osc/oscpack/OscPrintReceivedElements.cpp
- Implemented real-time state notification using OSC-UDP.
[casparcg] / protocol / osc / oscpack / OscPrintReceivedElements.cpp
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 #undef _CRT_SECURE_NO_WARNINGS
31 #define _CRT_SECURE_NO_WARNINGS
32
33 #include "OscPrintReceivedElements.h"
34
35 #include <iostream>
36 #include <iomanip>
37 #include <ctime>
38 #include <cstring>
39
40
41 namespace osc{
42
43
44 std::ostream& operator<<( std::ostream & os,
45         const ReceivedMessageArgument& arg )
46 {
47     switch( arg.TypeTag() ){
48         case TRUE_TYPE_TAG:
49             os << "bool:true";
50             break;
51                 
52         case FALSE_TYPE_TAG:
53             os << "bool:false";
54             break;
55
56         case NIL_TYPE_TAG:
57             os << "(Nil)";
58             break;
59
60         case INFINITUM_TYPE_TAG:
61             os << "(Infinitum)";
62             break;
63
64         case INT32_TYPE_TAG:
65             os << "int32:" << arg.AsInt32Unchecked();
66             break;
67
68         case FLOAT_TYPE_TAG:
69             os << "float32:" << arg.AsFloatUnchecked();
70             break;
71
72         case CHAR_TYPE_TAG:
73             {
74                 char s[2] = {0};
75                 s[0] = arg.AsCharUnchecked();
76                 os << "char:'" << s << "'";
77             }
78             break;
79
80         case RGBA_COLOR_TYPE_TAG:
81             {
82                 uint32 color = arg.AsRgbaColorUnchecked();
83                 
84                 os << "RGBA:0x"
85                         << std::hex << std::setfill('0')
86                         << std::setw(2) << (int)((color>>24) & 0xFF)
87                         << std::setw(2) << (int)((color>>16) & 0xFF)
88                         << std::setw(2) << (int)((color>>8) & 0xFF)
89                         << std::setw(2) << (int)(color & 0xFF)
90                         << std::setfill(' ');
91                 os.unsetf(std::ios::basefield);
92             }
93             break;
94
95         case MIDI_MESSAGE_TYPE_TAG:
96             {
97                 uint32 m = arg.AsMidiMessageUnchecked();
98                 os << "midi (port, status, data1, data2):<<"
99                         << std::hex << std::setfill('0')
100                         << "0x" << std::setw(2) << (int)((m>>24) & 0xFF)
101                         << " 0x" << std::setw(2) << (int)((m>>16) & 0xFF)
102                         << " 0x" << std::setw(2) << (int)((m>>8) & 0xFF)
103                         << " 0x" << std::setw(2) << (int)(m & 0xFF)
104                         << std::setfill(' ') << ">>";
105                 os.unsetf(std::ios::basefield);
106             }
107             break;
108                                 
109         case INT64_TYPE_TAG:
110             os << "int64:" << arg.AsInt64Unchecked();
111             break;
112
113         case TIME_TAG_TYPE_TAG:
114             {
115                 os << "OSC-timetag:" << arg.AsTimeTagUnchecked();
116
117                 std::time_t t =
118                         (unsigned long)( arg.AsTimeTagUnchecked() >> 32 );
119
120                 // strip trailing newline from string returned by ctime
121                 const char *timeString = std::ctime( &t );
122                 size_t len = strlen( timeString );
123                 char *s = new char[ len + 1 ];
124                 strcpy( s, timeString );
125                 if( len )
126                     s[ len - 1 ] = '\0';
127                     
128                 os << " " << s;
129             }
130             break;
131                 
132         case DOUBLE_TYPE_TAG:
133             os << "double:" << arg.AsDoubleUnchecked();
134             break;
135
136         case STRING_TYPE_TAG:
137             os << "OSC-string:`" << arg.AsStringUnchecked() << "'";
138             break;
139                 
140         case SYMBOL_TYPE_TAG: 
141             os << "OSC-string (symbol):`" << arg.AsSymbolUnchecked() << "'";
142             break;
143
144         case BLOB_TYPE_TAG:
145             {
146                 unsigned long size;
147                 const void *data;
148                 arg.AsBlobUnchecked( data, size );
149                 os << "OSC-blob:<<" << std::hex << std::setfill('0');
150                 unsigned char *p = (unsigned char*)data;
151                 for( unsigned long i = 0; i < size; ++i ){
152                     os << "0x" << std::setw(2) << int(p[i]);
153                     if( i != size-1 )
154                         os << ' ';
155                 }
156                 os.unsetf(std::ios::basefield);
157                 os << ">>" << std::setfill(' ');
158             }
159             break;
160
161         default:
162             os << "unknown";
163     }
164
165     return os;
166 }
167
168
169 std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m )
170 {
171     os << "[";
172     if( m.AddressPatternIsUInt32() )
173         os << m.AddressPatternAsUInt32();
174     else
175         os << m.AddressPattern();
176     
177     bool first = true;
178     for( ReceivedMessage::const_iterator i = m.ArgumentsBegin();
179             i != m.ArgumentsEnd(); ++i ){
180         if( first ){
181             os << " ";
182             first = false;
183         }else{
184             os << ", ";
185         }
186
187         os << *i;
188     }
189
190     os << "]";
191
192     return os;
193 }
194
195
196 std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b )
197 {
198     static int indent = 0;
199
200     for( int j=0; j < indent; ++j )
201         os << "  ";
202     os << "{ ( ";
203     if( b.TimeTag() == 1 )
204         os << "immediate";
205     else
206         os << b.TimeTag();
207     os << " )\n";
208
209     ++indent;
210     
211     for( ReceivedBundle::const_iterator i = b.ElementsBegin();
212             i != b.ElementsEnd(); ++i ){
213         if( i->IsBundle() ){
214             ReceivedBundle b(*i);
215             os << b << "\n";
216         }else{
217             ReceivedMessage m(*i);
218             for( int j=0; j < indent; ++j )
219                 os << "  ";
220             os << m << "\n";
221         }
222     }
223
224     --indent;
225
226     for( int j=0; j < indent; ++j )
227         os << "  ";
228     os << "}";
229
230     return os;
231 }
232
233
234 std::ostream& operator<<( std::ostream & os, const ReceivedPacket& p )
235 {
236     if( p.IsBundle() ){
237         ReceivedBundle b(p);
238         os << b << "\n";
239     }else{
240         ReceivedMessage m(p);
241         os << m << "\n";
242     }
243
244     return os;
245 }
246
247 } // namespace osc