2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "SC_Endian.h"
29 // return the ptr to the byte after the OSC string.
30 inline const char* OSCstrskip(const char *str
)
32 // while (str[3]) { str += 4; }
34 do { str
+= 4; } while (str
[-1]);
38 // returns the number of bytes (including padding) for an OSC string.
39 inline int OSCstrlen(const char *strin
)
41 return OSCstrskip(strin
) - strin
;
44 // returns a float, converting an int if necessary
45 inline float32
OSCfloat(const char* inData
)
48 elem
.u
= ntohl(*(uint32
*)inData
);
52 inline int32
OSCint(const char* inData
)
54 return (int32
)ntohl(*(uint32
*)inData
);
57 inline int64
OSCtime(const char* inData
)
59 return ((int64
)ntohl(*(uint32
*)inData
) << 32) + (ntohl(*(uint32
*)(inData
+ 4)));
62 inline float64
OSCdouble(const char* inData
)
65 slot
.i
= ((int64
)ntohl(*(uint32
*)inData
) << 32) + (ntohl(*(uint32
*)(inData
+ 4)));
71 const char *data
, *rdpos
, *endpos
, *tags
;
75 sc_msg_iter(int inSize
, const char* inData
);
76 void init(int inSize
, const char* inData
);
77 int32
geti(int32 defaultValue
= 0);
78 float32
getf(float32 defaultValue
= 0.f
);
79 float64
getd(float64 defaultValue
= 0.f
);
80 const char *gets(const char* defaultValue
= 0);
81 int32
*gets4(char* defaultValue
= 0);
83 void getb(char* outData
, size_t inSize
);
85 int remain() { return endpos
- rdpos
; }
87 char nextTag(char defaultTag
= 'f') { return tags
? tags
[count
] : defaultTag
; }
90 inline sc_msg_iter::sc_msg_iter()
94 inline sc_msg_iter::sc_msg_iter(int inSize
, const char* inData
)
99 inline void sc_msg_iter::init(int inSize
, const char* inData
)
103 endpos
= data
+ size
;
105 if (data
[0] == ',') {
107 rdpos
= OSCstrskip(data
);
114 inline int32
sc_msg_iter::geti(int32 defaultValue
)
117 if (remain() <= 0) return defaultValue
;
119 if (tags
[count
] == 'i') {
120 value
= OSCint(rdpos
);
121 rdpos
+= sizeof(int32
);
122 } else if (tags
[count
] == 'f') {
123 value
= (int32
)OSCfloat(rdpos
);
124 rdpos
+= sizeof(float32
);
125 } else if (tags
[count
] == 's') {
126 /* value = atoi(rdpos); */
127 value
= defaultValue
;
128 rdpos
= OSCstrskip(rdpos
);
129 } else if (tags
[count
] == 'b') {
130 value
= defaultValue
;
133 /* this is dangerous, as rdpos is not
134 advanced accordingly while count++ takes
136 value
= defaultValue
;
139 value
= (int)OSCint(rdpos
);
140 rdpos
+= sizeof(int32
);
146 inline float32
sc_msg_iter::getf(float32 defaultValue
)
149 if (remain() <= 0) return defaultValue
;
151 if (tags
[count
] == 'f') {
152 value
= OSCfloat(rdpos
);
153 rdpos
+= sizeof(float32
);
154 } else if (tags
[count
] == 'd') {
155 value
= static_cast<float32
>(OSCdouble(rdpos
));
156 rdpos
+= sizeof(float64
);
157 } else if (tags
[count
] == 'i') {
158 value
= static_cast<float32
>(OSCint(rdpos
));
159 rdpos
+= sizeof(int32
);
160 } else if (tags
[count
] == 's') {
161 /* value = atof(rdpos); */
162 value
= defaultValue
;
163 rdpos
= OSCstrskip(rdpos
);
164 } else if (tags
[count
] == 'b') {
165 value
= defaultValue
;
168 /* this is dangerous, as rdpos is not
169 advanced accordingly while count++ takes
171 value
= defaultValue
;
174 value
= OSCfloat(rdpos
);
175 rdpos
+= sizeof(float32
);
181 inline float64
sc_msg_iter::getd(float64 defaultValue
)
184 if (remain() <= 0) return defaultValue
;
186 if (tags
[count
] == 'f') {
187 value
= (float64
)OSCfloat(rdpos
);
188 rdpos
+= sizeof(float32
);
189 } else if (tags
[count
] == 'd') {
190 value
= OSCdouble(rdpos
);
191 rdpos
+= sizeof(float64
);
192 } else if (tags
[count
] == 'i') {
193 value
= (float64
)OSCint(rdpos
);
194 rdpos
+= sizeof(int32
);
195 } else if (tags
[count
] == 's') {
196 /* value = atof(rdpos); */
197 value
= defaultValue
;
198 rdpos
= OSCstrskip(rdpos
);
199 } else if (tags
[count
] == 'b') {
200 value
= defaultValue
;
203 /* this is dangerous, as rdpos is not
204 advanced accordingly while count++ takes
206 value
= defaultValue
;
209 value
= OSCdouble(rdpos
);
210 rdpos
+= sizeof(float64
);
217 inline const char* sc_msg_iter::gets(const char* defaultValue
)
220 if (remain() <= 0) return 0;
222 if (tags
[count
] == 's') {
224 rdpos
= OSCstrskip(rdpos
);
226 value
= defaultValue
;
230 rdpos
= OSCstrskip(rdpos
);
236 inline int32
* sc_msg_iter::gets4(char* defaultValue
)
239 if (remain() <= 0) return 0;
241 if (tags
[count
] == 's') {
242 value
= (int32
*)rdpos
;
243 rdpos
= OSCstrskip(rdpos
);
245 value
= (int32
*)defaultValue
;
248 value
= (int32
*)rdpos
;
249 rdpos
= OSCstrskip(rdpos
);
255 inline size_t sc_msg_iter::getbsize()
257 if (remain() <= 0) return 0;
258 if (tags
&& tags
[count
] != 'b') return 0;
259 return (size_t)OSCint(rdpos
);
262 inline void sc_msg_iter::getb(char* outArray
, size_t size
)
264 size_t len
= OSCint(rdpos
);
265 if (size
< len
) return;
266 rdpos
+= sizeof(int32
);
267 size_t len4
= (len
+ 3) & (size_t)-4;
268 memcpy(outArray
, rdpos
, size
);
273 inline void sc_msg_iter::skipb()
275 size_t len
= OSCint(rdpos
);
276 rdpos
+= sizeof(int32
);
277 size_t len4
= (len
+ 3) & (size_t)-4;