rob@76
|
1 /*
|
rob@76
|
2 oscpack -- Open Sound Control (OSC) packet manipulation library
|
rob@76
|
3 http://www.rossbencina.com/code/oscpack
|
rob@76
|
4
|
rob@76
|
5 Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com>
|
rob@76
|
6
|
rob@76
|
7 Permission is hereby granted, free of charge, to any person obtaining
|
rob@76
|
8 a copy of this software and associated documentation files
|
rob@76
|
9 (the "Software"), to deal in the Software without restriction,
|
rob@76
|
10 including without limitation the rights to use, copy, modify, merge,
|
rob@76
|
11 publish, distribute, sublicense, and/or sell copies of the Software,
|
rob@76
|
12 and to permit persons to whom the Software is furnished to do so,
|
rob@76
|
13 subject to the following conditions:
|
rob@76
|
14
|
rob@76
|
15 The above copyright notice and this permission notice shall be
|
rob@76
|
16 included in all copies or substantial portions of the Software.
|
rob@76
|
17
|
rob@76
|
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
rob@76
|
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
rob@76
|
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
rob@76
|
21 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
rob@76
|
22 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
rob@76
|
23 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
rob@76
|
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
rob@76
|
25 */
|
rob@76
|
26
|
rob@76
|
27 /*
|
rob@76
|
28 The text above constitutes the entire oscpack license; however,
|
rob@76
|
29 the oscpack developer(s) also make the following non-binding requests:
|
rob@76
|
30
|
rob@76
|
31 Any person wishing to distribute modifications to the Software is
|
rob@76
|
32 requested to send the modifications to the original developer so that
|
rob@76
|
33 they can be incorporated into the canonical version. It is also
|
rob@76
|
34 requested that these non-binding requests be included whenever the
|
rob@76
|
35 above license is reproduced.
|
rob@76
|
36 */
|
rob@76
|
37 #include "OscPrintReceivedElements.h"
|
rob@76
|
38
|
rob@76
|
39 #include <cstring>
|
rob@76
|
40 #include <ctime>
|
rob@76
|
41 #include <iostream>
|
rob@76
|
42 #include <iomanip>
|
rob@76
|
43
|
rob@76
|
44 #if defined(__BORLANDC__) // workaround for BCB4 release build intrinsics bug
|
rob@76
|
45 namespace std {
|
rob@76
|
46 using ::__strcpy__; // avoid error: E2316 '__strcpy__' is not a member of 'std'.
|
rob@76
|
47 }
|
rob@76
|
48 #endif
|
rob@76
|
49
|
rob@76
|
50 namespace osc{
|
rob@76
|
51
|
rob@76
|
52
|
rob@76
|
53 std::ostream& operator<<( std::ostream & os,
|
rob@76
|
54 const ReceivedMessageArgument& arg )
|
rob@76
|
55 {
|
rob@76
|
56 switch( arg.TypeTag() ){
|
rob@76
|
57 case TRUE_TYPE_TAG:
|
rob@76
|
58 os << "bool:true";
|
rob@76
|
59 break;
|
rob@76
|
60
|
rob@76
|
61 case FALSE_TYPE_TAG:
|
rob@76
|
62 os << "bool:false";
|
rob@76
|
63 break;
|
rob@76
|
64
|
rob@76
|
65 case NIL_TYPE_TAG:
|
rob@76
|
66 os << "(Nil)";
|
rob@76
|
67 break;
|
rob@76
|
68
|
rob@76
|
69 case INFINITUM_TYPE_TAG:
|
rob@76
|
70 os << "(Infinitum)";
|
rob@76
|
71 break;
|
rob@76
|
72
|
rob@76
|
73 case INT32_TYPE_TAG:
|
rob@76
|
74 os << "int32:" << arg.AsInt32Unchecked();
|
rob@76
|
75 break;
|
rob@76
|
76
|
rob@76
|
77 case FLOAT_TYPE_TAG:
|
rob@76
|
78 os << "float32:" << arg.AsFloatUnchecked();
|
rob@76
|
79 break;
|
rob@76
|
80
|
rob@76
|
81 case CHAR_TYPE_TAG:
|
rob@76
|
82 {
|
rob@76
|
83 char s[2] = {0};
|
rob@76
|
84 s[0] = arg.AsCharUnchecked();
|
rob@76
|
85 os << "char:'" << s << "'";
|
rob@76
|
86 }
|
rob@76
|
87 break;
|
rob@76
|
88
|
rob@76
|
89 case RGBA_COLOR_TYPE_TAG:
|
rob@76
|
90 {
|
rob@76
|
91 uint32 color = arg.AsRgbaColorUnchecked();
|
rob@76
|
92
|
rob@76
|
93 os << "RGBA:0x"
|
rob@76
|
94 << std::hex << std::setfill('0')
|
rob@76
|
95 << std::setw(2) << (int)((color>>24) & 0xFF)
|
rob@76
|
96 << std::setw(2) << (int)((color>>16) & 0xFF)
|
rob@76
|
97 << std::setw(2) << (int)((color>>8) & 0xFF)
|
rob@76
|
98 << std::setw(2) << (int)(color & 0xFF)
|
rob@76
|
99 << std::setfill(' ');
|
rob@76
|
100 os.unsetf(std::ios::basefield);
|
rob@76
|
101 }
|
rob@76
|
102 break;
|
rob@76
|
103
|
rob@76
|
104 case MIDI_MESSAGE_TYPE_TAG:
|
rob@76
|
105 {
|
rob@76
|
106 uint32 m = arg.AsMidiMessageUnchecked();
|
rob@76
|
107 os << "midi (port, status, data1, data2):<<"
|
rob@76
|
108 << std::hex << std::setfill('0')
|
rob@76
|
109 << "0x" << std::setw(2) << (int)((m>>24) & 0xFF)
|
rob@76
|
110 << " 0x" << std::setw(2) << (int)((m>>16) & 0xFF)
|
rob@76
|
111 << " 0x" << std::setw(2) << (int)((m>>8) & 0xFF)
|
rob@76
|
112 << " 0x" << std::setw(2) << (int)(m & 0xFF)
|
rob@76
|
113 << std::setfill(' ') << ">>";
|
rob@76
|
114 os.unsetf(std::ios::basefield);
|
rob@76
|
115 }
|
rob@76
|
116 break;
|
rob@76
|
117
|
rob@76
|
118 case INT64_TYPE_TAG:
|
rob@76
|
119 os << "int64:" << arg.AsInt64Unchecked();
|
rob@76
|
120 break;
|
rob@76
|
121
|
rob@76
|
122 case TIME_TAG_TYPE_TAG:
|
rob@76
|
123 {
|
rob@76
|
124 os << "OSC-timetag:" << arg.AsTimeTagUnchecked() << " ";
|
rob@76
|
125
|
rob@76
|
126 std::time_t t =
|
rob@76
|
127 (unsigned long)( arg.AsTimeTagUnchecked() >> 32 );
|
rob@76
|
128
|
rob@76
|
129 const char *timeString = std::ctime( &t );
|
rob@76
|
130 size_t len = std::strlen( timeString );
|
rob@76
|
131
|
rob@76
|
132 // -1 to omit trailing newline from string returned by ctime()
|
rob@76
|
133 if( len > 1 )
|
rob@76
|
134 os.write( timeString, len - 1 );
|
rob@76
|
135 }
|
rob@76
|
136 break;
|
rob@76
|
137
|
rob@76
|
138 case DOUBLE_TYPE_TAG:
|
rob@76
|
139 os << "double:" << arg.AsDoubleUnchecked();
|
rob@76
|
140 break;
|
rob@76
|
141
|
rob@76
|
142 case STRING_TYPE_TAG:
|
rob@76
|
143 os << "OSC-string:`" << arg.AsStringUnchecked() << "'";
|
rob@76
|
144 break;
|
rob@76
|
145
|
rob@76
|
146 case SYMBOL_TYPE_TAG:
|
rob@76
|
147 os << "OSC-string (symbol):`" << arg.AsSymbolUnchecked() << "'";
|
rob@76
|
148 break;
|
rob@76
|
149
|
rob@76
|
150 case BLOB_TYPE_TAG:
|
rob@76
|
151 {
|
rob@76
|
152 const void *data;
|
rob@76
|
153 osc_bundle_element_size_t size;
|
rob@76
|
154 arg.AsBlobUnchecked( data, size );
|
rob@76
|
155 os << "OSC-blob:<<" << std::hex << std::setfill('0');
|
rob@76
|
156 unsigned char *p = (unsigned char*)data;
|
rob@76
|
157 for( osc_bundle_element_size_t i = 0; i < size; ++i ){
|
rob@76
|
158 os << "0x" << std::setw(2) << int(p[i]);
|
rob@76
|
159 if( i != size-1 )
|
rob@76
|
160 os << ' ';
|
rob@76
|
161 }
|
rob@76
|
162 os.unsetf(std::ios::basefield);
|
rob@76
|
163 os << ">>" << std::setfill(' ');
|
rob@76
|
164 }
|
rob@76
|
165 break;
|
rob@76
|
166
|
rob@76
|
167 case ARRAY_BEGIN_TYPE_TAG:
|
rob@76
|
168 os << "[";
|
rob@76
|
169 break;
|
rob@76
|
170
|
rob@76
|
171 case ARRAY_END_TYPE_TAG:
|
rob@76
|
172 os << "]";
|
rob@76
|
173 break;
|
rob@76
|
174
|
rob@76
|
175 default:
|
rob@76
|
176 os << "unknown";
|
rob@76
|
177 }
|
rob@76
|
178
|
rob@76
|
179 return os;
|
rob@76
|
180 }
|
rob@76
|
181
|
rob@76
|
182
|
rob@76
|
183 std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m )
|
rob@76
|
184 {
|
rob@76
|
185 os << "[";
|
rob@76
|
186 if( m.AddressPatternIsUInt32() )
|
rob@76
|
187 os << m.AddressPatternAsUInt32();
|
rob@76
|
188 else
|
rob@76
|
189 os << m.AddressPattern();
|
rob@76
|
190
|
rob@76
|
191 bool first = true;
|
rob@76
|
192 for( ReceivedMessage::const_iterator i = m.ArgumentsBegin();
|
rob@76
|
193 i != m.ArgumentsEnd(); ++i ){
|
rob@76
|
194 if( first ){
|
rob@76
|
195 os << " ";
|
rob@76
|
196 first = false;
|
rob@76
|
197 }else{
|
rob@76
|
198 os << ", ";
|
rob@76
|
199 }
|
rob@76
|
200
|
rob@76
|
201 os << *i;
|
rob@76
|
202 }
|
rob@76
|
203
|
rob@76
|
204 os << "]";
|
rob@76
|
205
|
rob@76
|
206 return os;
|
rob@76
|
207 }
|
rob@76
|
208
|
rob@76
|
209
|
rob@76
|
210 std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b )
|
rob@76
|
211 {
|
rob@76
|
212 static int indent = 0;
|
rob@76
|
213
|
rob@76
|
214 for( int j=0; j < indent; ++j )
|
rob@76
|
215 os << " ";
|
rob@76
|
216 os << "{ ( ";
|
rob@76
|
217 if( b.TimeTag() == 1 )
|
rob@76
|
218 os << "immediate";
|
rob@76
|
219 else
|
rob@76
|
220 os << b.TimeTag();
|
rob@76
|
221 os << " )\n";
|
rob@76
|
222
|
rob@76
|
223 ++indent;
|
rob@76
|
224
|
rob@76
|
225 for( ReceivedBundle::const_iterator i = b.ElementsBegin();
|
rob@76
|
226 i != b.ElementsEnd(); ++i ){
|
rob@76
|
227 if( i->IsBundle() ){
|
rob@76
|
228 ReceivedBundle b(*i);
|
rob@76
|
229 os << b << "\n";
|
rob@76
|
230 }else{
|
rob@76
|
231 ReceivedMessage m(*i);
|
rob@76
|
232 for( int j=0; j < indent; ++j )
|
rob@76
|
233 os << " ";
|
rob@76
|
234 os << m << "\n";
|
rob@76
|
235 }
|
rob@76
|
236 }
|
rob@76
|
237
|
rob@76
|
238 --indent;
|
rob@76
|
239
|
rob@76
|
240 for( int j=0; j < indent; ++j )
|
rob@76
|
241 os << " ";
|
rob@76
|
242 os << "}";
|
rob@76
|
243
|
rob@76
|
244 return os;
|
rob@76
|
245 }
|
rob@76
|
246
|
rob@76
|
247
|
rob@76
|
248 std::ostream& operator<<( std::ostream & os, const ReceivedPacket& p )
|
rob@76
|
249 {
|
rob@76
|
250 if( p.IsBundle() ){
|
rob@76
|
251 ReceivedBundle b(p);
|
rob@76
|
252 os << b << "\n";
|
rob@76
|
253 }else{
|
rob@76
|
254 ReceivedMessage m(p);
|
rob@76
|
255 os << m << "\n";
|
rob@76
|
256 }
|
rob@76
|
257
|
rob@76
|
258 return os;
|
rob@76
|
259 }
|
rob@76
|
260
|
rob@76
|
261 } // namespace osc
|