1 /* GSequencer - Advanced GTK Sequencer
2 * Copyright (C) 2005-2019 Joël Krähemann
3 *
4 * This file is part of GSequencer.
5 *
6 * GSequencer 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 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GSequencer 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.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GSequencer. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <ags/audio/osc/ags_osc_parser.h>
21
22 #include <ags/audio/osc/ags_osc_util.h>
23
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include <ags/i18n.h>
28
29 void ags_osc_parser_class_init(AgsOscParserClass *osc_parser);
30 void ags_osc_parser_init(AgsOscParser *osc_parser);
31 void ags_osc_parser_set_property(GObject *gobject,
32 guint prop_id,
33 const GValue *value,
34 GParamSpec *param_spec);
35 void ags_osc_parser_get_property(GObject *gobject,
36 guint prop_id,
37 GValue *value,
38 GParamSpec *param_spec);
39 void ags_osc_parser_finalize(GObject *gobject);
40
41 int ags_osc_parser_real_osc_getc(AgsOscParser *osc_parser);
42 void ags_osc_parser_real_on_error(AgsOscParser *osc_parser,
43 GError **error);
44
45 xmlDoc* ags_osc_parser_real_parse_full(AgsOscParser *osc_parser);
46 xmlNode* ags_osc_parser_real_parse_bytes(AgsOscParser *osc_parser,
47 unsigned char *osc_buffer,
48 guint buffer_length);
49
50 xmlNode* ags_osc_parser_real_packet(AgsOscParser *osc_parser);
51
52 xmlNode* ags_osc_parser_real_bundle(AgsOscParser *osc_parser);
53
54 xmlNode* ags_osc_parser_real_message(AgsOscParser *osc_parser);
55
56 xmlNode* ags_osc_parser_real_value(AgsOscParser *osc_parser,
57 guint v_type);
58
59 /**
60 * SECTION:ags_osc_parser
61 * @short_description: the OSC parser
62 * @title: AgsOscParser
63 * @section_id:
64 * @include: ags/audio/osc/ags_osc_parser.h
65 *
66 * #AgsOscParser reads your osc parsers.
67 */
68
69 enum{
70 PROP_0,
71 };
72
73 enum{
74 OSC_GETC,
75 ON_ERROR,
76 PARSE_FULL,
77 PARSE_BYTES,
78 PACKET,
79 BUNDLE,
80 MESSAGE,
81 VALUE,
82 LAST_SIGNAL,
83 };
84
85 static gpointer ags_osc_parser_parent_class = NULL;
86 static guint osc_parser_signals[LAST_SIGNAL];
87
88 GType
ags_osc_parser_get_type(void)89 ags_osc_parser_get_type(void)
90 {
91 static volatile gsize g_define_type_id__volatile = 0;
92
93 if(g_once_init_enter (&g_define_type_id__volatile)){
94 GType ags_type_osc_parser = 0;
95
96 static const GTypeInfo ags_osc_parser_info = {
97 sizeof (AgsOscParserClass),
98 NULL, /* base_init */
99 NULL, /* base_finalize */
100 (GClassInitFunc) ags_osc_parser_class_init,
101 NULL, /* class_finalize */
102 NULL, /* class_data */
103 sizeof (AgsOscParser),
104 0, /* n_preallocs */
105 (GInstanceInitFunc) ags_osc_parser_init,
106 };
107
108 ags_type_osc_parser = g_type_register_static(G_TYPE_OBJECT,
109 "AgsOscParser", &ags_osc_parser_info,
110 0);
111
112 g_once_init_leave(&g_define_type_id__volatile, ags_type_osc_parser);
113 }
114
115 return g_define_type_id__volatile;
116 }
117
118 void
ags_osc_parser_class_init(AgsOscParserClass * osc_parser)119 ags_osc_parser_class_init(AgsOscParserClass *osc_parser)
120 {
121 GObjectClass *gobject;
122 GParamSpec *param_spec;
123
124 ags_osc_parser_parent_class = g_type_class_peek_parent(osc_parser);
125
126 /* GObjectClass */
127 gobject = (GObjectClass *) osc_parser;
128
129 gobject->set_property = ags_osc_parser_set_property;
130 gobject->get_property = ags_osc_parser_get_property;
131
132 gobject->finalize = ags_osc_parser_finalize;
133
134 /* AgsOscParser */
135 osc_parser->osc_getc = ags_osc_parser_real_osc_getc;
136 osc_parser->on_error = ags_osc_parser_real_on_error;
137
138 osc_parser->parse_full = ags_osc_parser_real_parse_full;
139 osc_parser->parse_bytes = ags_osc_parser_real_parse_bytes;
140
141 osc_parser->packet = ags_osc_parser_real_packet;
142
143 osc_parser->bundle = ags_osc_parser_real_bundle;
144
145 osc_parser->packet = ags_osc_parser_real_packet;
146
147 osc_parser->value = ags_osc_parser_real_value;
148
149 /* signals */
150 /**
151 * AgsOscParser::osc-getc:
152 * @osc_parser: the #AgsOscParser
153 *
154 * The ::osc-getc signal is emited during parsing of event.
155 *
156 * Returns: The character read
157 *
158 * Since: 3.0.0
159 */
160 osc_parser_signals[OSC_GETC] =
161 g_signal_new("osc-getc",
162 G_TYPE_FROM_CLASS(osc_parser),
163 G_SIGNAL_RUN_LAST,
164 G_STRUCT_OFFSET(AgsOscParserClass, osc_getc),
165 NULL, NULL,
166 ags_cclosure_marshal_INT__VOID,
167 G_TYPE_INT, 0);
168
169 /**
170 * AgsOscParser::on-error:
171 * @osc_parser: the #AgsOscParser
172 * @error: the return location of #GError
173 *
174 * The ::on-error signal is emited as error occurs.
175 *
176 * Since: 3.0.0
177 */
178 osc_parser_signals[ON_ERROR] =
179 g_signal_new("on-error",
180 G_TYPE_FROM_CLASS(osc_parser),
181 G_SIGNAL_RUN_LAST,
182 G_STRUCT_OFFSET(AgsOscParserClass, on_error),
183 NULL, NULL,
184 g_cclosure_marshal_VOID__POINTER,
185 G_TYPE_NONE, 1,
186 G_TYPE_POINTER);
187
188 /**
189 * AgsOscParser::parse-full:
190 * @osc_parser: the #AgsOscParser
191 *
192 * The ::parse-full signal is emited during parsing of osc file.
193 *
194 * Returns: The XML doc
195 *
196 * Since: 3.0.0
197 */
198 osc_parser_signals[PARSE_FULL] =
199 g_signal_new("parse-full",
200 G_TYPE_FROM_CLASS(osc_parser),
201 G_SIGNAL_RUN_LAST,
202 G_STRUCT_OFFSET(AgsOscParserClass, parse_full),
203 NULL, NULL,
204 ags_cclosure_marshal_POINTER__VOID,
205 G_TYPE_POINTER, 0);
206
207 /**
208 * AgsOscParser::parse-bytes:
209 * @osc_parser: the #AgsOscParser
210 * @buffer: the OSC data
211 * @buffer_length: the buffer's length
212 *
213 * The ::parse-bytes signal is emited during parsing of bytes.
214 *
215 * Returns: The XML node representing the event
216 *
217 * Since: 3.0.0
218 */
219 osc_parser_signals[PARSE_BYTES] =
220 g_signal_new("parse-bytes",
221 G_TYPE_FROM_CLASS(osc_parser),
222 G_SIGNAL_RUN_LAST,
223 G_STRUCT_OFFSET(AgsOscParserClass, parse_bytes),
224 NULL, NULL,
225 ags_cclosure_marshal_POINTER__POINTER_UINT,
226 G_TYPE_POINTER, 2,
227 G_TYPE_POINTER,
228 G_TYPE_UINT);
229
230 /**
231 * AgsOscParser::packet:
232 * @osc_parser: the #AgsOscParser
233 *
234 * The ::packet signal is emited during parsing.
235 *
236 * Returns: The XML node representing packet
237 *
238 * Since: 3.0.0
239 */
240 osc_parser_signals[PACKET] =
241 g_signal_new("packet",
242 G_TYPE_FROM_CLASS(osc_parser),
243 G_SIGNAL_RUN_LAST,
244 G_STRUCT_OFFSET(AgsOscParserClass, packet),
245 NULL, NULL,
246 ags_cclosure_marshal_POINTER__VOID,
247 G_TYPE_POINTER, 0);
248
249 /**
250 * AgsOscParser::bundle:
251 * @osc_parser: the #AgsOscParser
252 *
253 * The ::bundle signal is emited during parsing.
254 *
255 * Returns: The XML node representing bundle
256 *
257 * Since: 3.0.0
258 */
259 osc_parser_signals[BUNDLE] =
260 g_signal_new("bundle",
261 G_TYPE_FROM_CLASS(osc_parser),
262 G_SIGNAL_RUN_LAST,
263 G_STRUCT_OFFSET(AgsOscParserClass, bundle),
264 NULL, NULL,
265 ags_cclosure_marshal_POINTER__VOID,
266 G_TYPE_POINTER, 0);
267
268 /**
269 * AgsOscParser::message:
270 * @osc_parser: the #AgsOscParser
271 *
272 * The ::message signal is emited during parsing.
273 *
274 * Returns: The XML node representing message
275 *
276 * Since: 3.0.0
277 */
278 osc_parser_signals[MESSAGE] =
279 g_signal_new("message",
280 G_TYPE_FROM_CLASS(osc_parser),
281 G_SIGNAL_RUN_LAST,
282 G_STRUCT_OFFSET(AgsOscParserClass, message),
283 NULL, NULL,
284 ags_cclosure_marshal_POINTER__VOID,
285 G_TYPE_POINTER, 0);
286
287 /**
288 * AgsOscParser::value:
289 * @osc_parser: the #AgsOscParser
290 * @v_type: value type
291 *
292 * The ::value signal is emited during parsing.
293 *
294 * Returns: The XML node representing value
295 *
296 * Since: 3.0.0
297 */
298 osc_parser_signals[VALUE] =
299 g_signal_new("value",
300 G_TYPE_FROM_CLASS(osc_parser),
301 G_SIGNAL_RUN_LAST,
302 G_STRUCT_OFFSET(AgsOscParserClass, value),
303 NULL, NULL,
304 ags_cclosure_marshal_POINTER__UINT,
305 G_TYPE_POINTER, 1,
306 G_TYPE_UINT);
307 }
308
309 void
ags_osc_parser_init(AgsOscParser * osc_parser)310 ags_osc_parser_init(AgsOscParser *osc_parser)
311 {
312 osc_parser->flags = 0;
313
314 /* osc parser mutex */
315 g_rec_mutex_init(&(osc_parser->obj_mutex));
316
317 osc_parser->buffer = NULL;
318
319 osc_parser->file_length = 0;
320 osc_parser->offset = 0;
321
322 osc_parser->start_offset = 0;
323 osc_parser->packet_size = 0;
324
325 osc_parser->doc = NULL;
326 }
327
328 void
ags_osc_parser_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)329 ags_osc_parser_set_property(GObject *gobject,
330 guint prop_id,
331 const GValue *value,
332 GParamSpec *param_spec)
333 {
334 AgsOscParser *osc_parser;
335
336 GRecMutex *osc_parser_mutex;
337
338 osc_parser = AGS_OSC_PARSER(gobject);
339
340 /* get osc parser mutex */
341 osc_parser_mutex = AGS_OSC_PARSER_GET_OBJ_MUTEX(osc_parser);
342
343 switch(prop_id){
344 default:
345 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
346 break;
347 }
348 }
349
350 void
ags_osc_parser_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)351 ags_osc_parser_get_property(GObject *gobject,
352 guint prop_id,
353 GValue *value,
354 GParamSpec *param_spec)
355 {
356 AgsOscParser *osc_parser;
357
358 GRecMutex *osc_parser_mutex;
359
360 osc_parser = AGS_OSC_PARSER(gobject);
361
362 /* get osc parser mutex */
363 osc_parser_mutex = AGS_OSC_PARSER_GET_OBJ_MUTEX(osc_parser);
364
365 switch(prop_id){
366 default:
367 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
368 break;
369 }
370 }
371
372 void
ags_osc_parser_finalize(GObject * gobject)373 ags_osc_parser_finalize(GObject *gobject)
374 {
375 AgsOscParser *osc_parser;
376
377 osc_parser = (AgsOscParser *) gobject;
378
379 /* call parent */
380 G_OBJECT_CLASS(ags_osc_parser_parent_class)->finalize(gobject);
381 }
382
383 /**
384 * ags_osc_parser_read_gint32:
385 * @osc_parser: the #AgsOscParser
386 *
387 * Read 32 bit integer.
388 *
389 * Returns: the gint32 read
390 *
391 * Since: 3.0.0
392 */
393 gint32
ags_osc_parser_read_gint32(AgsOscParser * osc_parser)394 ags_osc_parser_read_gint32(AgsOscParser *osc_parser)
395 {
396 char str[4];
397 gint32 value;
398
399 str[0] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
400 str[1] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
401 str[2] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
402 str[3] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
403
404 value = (str[0] & 0xff);
405 value = (value<<8) + (str[1] & 0xff);
406 value = (value<<8) + (str[2] & 0xff);
407 value = (value<<8) + (str[3] & 0xff);
408
409 return(value);
410 }
411
412 /**
413 * ags_osc_parser_read_gint64:
414 * @osc_parser: the #AgsOscParser
415 *
416 * Read 64 bit integer.
417 *
418 * Returns: the gint64 read
419 *
420 * Since: 3.0.0
421 */
422 gint64
ags_osc_parser_read_gint64(AgsOscParser * osc_parser)423 ags_osc_parser_read_gint64(AgsOscParser *osc_parser)
424 {
425 char str[8];
426 gint64 value;
427
428 str[0] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
429 str[1] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
430 str[2] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
431 str[3] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
432 str[4] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
433 str[5] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
434 str[6] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
435 str[7] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
436
437 value = (str[0] & 0xff);
438 value = (value << 8) + (str[1] & 0xff);
439 value = (value << 8) + (str[2] & 0xff);
440 value = (value << 8) + (str[3] & 0xff);
441 value = (value << 8) + (str[4] & 0xff);
442 value = (value << 8) + (str[5] & 0xff);
443 value = (value << 8) + (str[6] & 0xff);
444 value = (value << 8) + (str[7] & 0xff);
445
446 return(value);
447 }
448
449 /**
450 * ags_osc_parser_read_gfloat:
451 * @osc_parser: the #AgsOscParser
452 *
453 * Read floating point value.
454 *
455 * Returns: the gfloat read
456 *
457 * Since: 3.0.0
458 */
459 gfloat
ags_osc_parser_read_gfloat(AgsOscParser * osc_parser)460 ags_osc_parser_read_gfloat(AgsOscParser *osc_parser)
461 {
462 char str[4];
463 union{
464 guint32 val;
465 GFloatIEEE754 ieee_float;
466 }data;
467
468 str[0] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
469 str[1] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
470 str[2] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
471 str[3] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
472
473 data.val = (str[0] & 0xff);
474 data.val = (data.val<<8) + (str[1] & 0xff);
475 data.val = (data.val<<8) + (str[2] & 0xff);
476 data.val = (data.val<<8) + (str[3] & 0xff);
477
478 return(data.ieee_float.v_float);
479 }
480
481 /**
482 * ags_osc_parser_read_gdouble:
483 * @osc_parser: the #AgsOscParser
484 *
485 * Read double precision floating point value.
486 *
487 * Returns: the gdouble read
488 *
489 * Since: 3.0.0
490 */
491 gdouble
ags_osc_parser_read_gdouble(AgsOscParser * osc_parser)492 ags_osc_parser_read_gdouble(AgsOscParser *osc_parser)
493 {
494 char str[8];
495 union{
496 guint64 val;
497 GDoubleIEEE754 ieee_double;
498 }data;
499
500 str[0] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
501 str[1] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
502 str[2] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
503 str[3] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
504 str[4] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
505 str[5] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
506 str[6] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
507 str[7] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
508
509 data.val = (str[0] & 0xff);
510 data.val = (data.val << 8) + (str[1] & 0xff);
511 data.val = (data.val << 8) + (str[2] & 0xff);
512 data.val = (data.val << 8) + (str[3] & 0xff);
513 data.val = (data.val << 8) + (str[4] & 0xff);
514 data.val = (data.val << 8) + (str[5] & 0xff);
515 data.val = (data.val << 8) + (str[6] & 0xff);
516 data.val = (data.val << 8) + (str[7] & 0xff);
517
518 return(data.ieee_double.v_double);
519 }
520
521 /**
522 * ags_osc_parser_read_text:
523 * @osc_parser: the #AgsOscParser
524 * @length: the length
525 *
526 * Read text.
527 *
528 * Returns: the text read as string
529 *
530 * Since: 3.0.0
531 */
532 gchar*
ags_osc_parser_read_text(AgsOscParser * osc_parser,gint length)533 ags_osc_parser_read_text(AgsOscParser *osc_parser,
534 gint length)
535 {
536 gchar text[AGS_OSC_PARSER_MAX_TEXT_LENGTH + 1];
537
538 gchar c;
539 guint i;
540
541 memset(text, 0, AGS_OSC_PARSER_MAX_TEXT_LENGTH * sizeof(char));
542 i = 0;
543
544 while((length <= 0 ||
545 i < length) &&
546 (AGS_OSC_PARSER_EOF & (osc_parser->flags)) == 0 &&
547 i < AGS_OSC_PARSER_MAX_TEXT_LENGTH){
548 (c = (char) 0xff & (ags_osc_parser_osc_getc(osc_parser)));
549
550 if(c == '\0'){
551 break;
552 }
553
554 text[i] = c;
555 i++;
556 }
557
558 text[i] = '\0';
559
560 return(g_strdup(text));
561 }
562
563 int
ags_osc_parser_real_osc_getc(AgsOscParser * osc_parser)564 ags_osc_parser_real_osc_getc(AgsOscParser *osc_parser)
565 {
566 int c;
567
568 if(osc_parser->offset >= osc_parser->file_length){
569 osc_parser->flags |= AGS_OSC_PARSER_EOF;
570
571 return(-1);
572 }
573
574 c = (int) osc_parser->buffer[osc_parser->offset];
575 osc_parser->offset += 1;
576
577 return(c);
578 }
579
580 /**
581 * ags_osc_parser_osc_getc:
582 * @osc_parser: the #AgsOscParser
583 *
584 * Read byte.
585 *
586 * Returns: the byte read
587 *
588 * Since: 3.0.0
589 */
590 int
ags_osc_parser_osc_getc(AgsOscParser * osc_parser)591 ags_osc_parser_osc_getc(AgsOscParser *osc_parser)
592 {
593 int c;
594
595 g_return_val_if_fail(AGS_IS_OSC_PARSER(osc_parser), '\0');
596
597 g_object_ref((GObject *) osc_parser);
598 g_signal_emit(G_OBJECT(osc_parser),
599 osc_parser_signals[OSC_GETC], 0,
600 &c);
601 g_object_unref((GObject *) osc_parser);
602
603 return(c);
604 }
605
606 void
ags_osc_parser_real_on_error(AgsOscParser * osc_parser,GError ** error)607 ags_osc_parser_real_on_error(AgsOscParser *osc_parser,
608 GError **error)
609 {
610 //TODO:JK: implement me
611 }
612
613 /**
614 * ags_osc_parser_on_error:
615 * @osc_parser: the #AgsOscParser
616 * @error: the #GError-struct return location
617 *
618 * On error event.
619 *
620 * Since: 3.0.0
621 */
622 void
ags_osc_parser_on_error(AgsOscParser * osc_parser,GError ** error)623 ags_osc_parser_on_error(AgsOscParser *osc_parser,
624 GError **error)
625 {
626 g_return_if_fail(AGS_IS_OSC_PARSER(osc_parser));
627
628 g_object_ref((GObject *) osc_parser);
629 g_signal_emit(G_OBJECT(osc_parser),
630 osc_parser_signals[ON_ERROR], 0,
631 error);
632 g_object_unref((GObject *) osc_parser);
633 }
634
635 xmlDoc*
ags_osc_parser_real_parse_full(AgsOscParser * osc_parser)636 ags_osc_parser_real_parse_full(AgsOscParser *osc_parser)
637 {
638 xmlDoc *doc;
639 xmlNode *root_node;
640 xmlNode *packets_node;
641 xmlNode *current;
642
643 /* create xmlDoc and set root node */
644 osc_parser->doc =
645 doc = xmlNewDoc("1.0");
646 root_node = xmlNewNode(NULL, "osc");
647 xmlDocSetRootElement(doc, root_node);
648
649 /* create packets node */
650 packets_node = xmlNewNode(NULL, "osc-packets");
651
652 /* parse packets */
653 xmlAddChild(root_node,
654 packets_node);
655
656 osc_parser->offset = 0;
657
658 while(((AGS_OSC_PARSER_EOF & (osc_parser->flags))) == 0){
659 current = ags_osc_parser_packet(osc_parser);
660
661 if(current != NULL){
662 xmlAddChild(packets_node,
663 current);
664 #ifdef AGS_DEBUG
665 g_message("parsed packet");
666 #endif
667 }else{
668 g_warning("skipped input");
669 }
670 }
671
672 return(doc);
673 }
674
675 /**
676 * ags_osc_parser_parse_full:
677 * @osc_parser: the #AgsOscParser
678 *
679 * Parse full document.
680 *
681 * Returns: (transfer none): the parsed XML doc
682 *
683 * Since: 3.0.0
684 */
685 xmlDoc*
ags_osc_parser_parse_full(AgsOscParser * osc_parser)686 ags_osc_parser_parse_full(AgsOscParser *osc_parser)
687 {
688 xmlDoc *doc;
689
690 g_return_val_if_fail(AGS_IS_OSC_PARSER(osc_parser), NULL);
691
692 g_object_ref((GObject *) osc_parser);
693 g_signal_emit(G_OBJECT(osc_parser),
694 osc_parser_signals[PARSE_FULL], 0,
695 &doc);
696 g_object_unref((GObject *) osc_parser);
697
698 return(doc);
699 }
700
701 xmlNode*
ags_osc_parser_real_parse_bytes(AgsOscParser * osc_parser,unsigned char * osc_buffer,guint buffer_length)702 ags_osc_parser_real_parse_bytes(AgsOscParser *osc_parser,
703 unsigned char *osc_buffer,
704 guint buffer_length)
705 {
706 xmlNode *node;
707
708 node = NULL;
709
710 //TODO:JK: implement me
711
712 return(node);
713 }
714
715 /**
716 * ags_osc_parser_parse_bytes:
717 * @osc_parser: the #AgsOscParser
718 * @osc_buffer: the data buffer
719 * @buffer_length: the length of data buffer
720 *
721 * Parse bytes.
722 *
723 * Returns: (transfer none): the parsed XML node
724 *
725 * Since: 3.0.0
726 */
727 xmlNode*
ags_osc_parser_parse_bytes(AgsOscParser * osc_parser,unsigned char * osc_buffer,guint buffer_length)728 ags_osc_parser_parse_bytes(AgsOscParser *osc_parser,
729 unsigned char *osc_buffer,
730 guint buffer_length)
731 {
732 xmlNode *node;
733
734 g_return_val_if_fail(AGS_IS_OSC_PARSER(osc_parser), NULL);
735
736 g_object_ref((GObject *) osc_parser);
737 g_signal_emit(G_OBJECT(osc_parser),
738 osc_parser_signals[PARSE_BYTES], 0,
739 &node);
740 g_object_unref((GObject *) osc_parser);
741
742 return(node);
743 }
744
745 xmlNode*
ags_osc_parser_real_packet(AgsOscParser * osc_parser)746 ags_osc_parser_real_packet(AgsOscParser *osc_parser)
747 {
748 xmlNode *node, *current;
749
750 gsize start_offset;
751 gint32 packet_size;
752 gchar current_byte;
753
754 node = xmlNewNode(NULL, "osc-packet");
755
756 packet_size =
757 osc_parser->packet_size = ags_osc_parser_read_gint32(osc_parser);
758 xmlNewProp(node,
759 "packet-size",
760 g_strdup_printf("%u", packet_size));
761
762 current_byte = ags_osc_parser_osc_getc(osc_parser);
763
764 start_offset =
765 osc_parser->start_offset = osc_parser->offset;
766
767 while(osc_parser->offset < start_offset + packet_size){
768 if(current_byte == '#'){
769 current = ags_osc_parser_bundle(osc_parser);
770 }else if(current_byte == '/'){
771 current = ags_osc_parser_message(osc_parser);
772 }else{
773 current = NULL;
774
775 g_warning("failed to read bundle or message");
776 }
777
778 if(current != NULL){
779 xmlAddChild(node,
780 current);
781 }
782 }
783
784 return(node);
785 }
786
787 /**
788 * ags_osc_parser_packet:
789 * @osc_parser: the #AgsOscParser
790 *
791 * Parse OSC packet.
792 *
793 * Returns: (transfer none): the parsed XML node
794 *
795 * Since: 3.0.0
796 */
797 xmlNode*
ags_osc_parser_packet(AgsOscParser * osc_parser)798 ags_osc_parser_packet(AgsOscParser *osc_parser)
799 {
800 xmlNode *node;
801
802 g_return_val_if_fail(AGS_IS_OSC_PARSER(osc_parser), NULL);
803
804 g_object_ref((GObject *) osc_parser);
805 g_signal_emit(G_OBJECT(osc_parser),
806 osc_parser_signals[PACKET], 0,
807 &node);
808 g_object_unref((GObject *) osc_parser);
809
810 return(node);
811 }
812
813 xmlNode*
ags_osc_parser_real_bundle(AgsOscParser * osc_parser)814 ags_osc_parser_real_bundle(AgsOscParser *osc_parser)
815 {
816 xmlNode *node, *current;
817
818 gint32 tv_secs;
819 gint32 tv_fraction;
820 gboolean immediately;
821 guint i;
822 gchar current_byte;
823
824 static gchar bundle[] = "#bundle";
825
826 for(i = 0; i < 7; i++){
827 gchar c;
828
829 c = ags_osc_parser_osc_getc(osc_parser);
830
831 if(c != bundle[i + 1]){
832 g_warning("bad byte");
833
834 return(NULL);
835 }
836 }
837
838 node = xmlNewNode(NULL,
839 "osc-bundle");
840
841 /* read time tag */
842 tv_secs = ags_osc_parser_read_gint32(osc_parser);
843 tv_fraction = ags_osc_parser_read_gint32(osc_parser);
844
845 immediately = FALSE;
846
847 if((0x1 & (tv_fraction)) != 0){
848 immediately = TRUE;
849 }
850
851 /* add prop */
852 xmlNewProp(node,
853 "tv-secs",
854 g_strdup_printf("%u", tv_secs));
855
856 xmlNewProp(node,
857 "tv-fraction",
858 g_strdup_printf("%u", tv_fraction));
859
860 xmlNewProp(node,
861 "immediately",
862 g_strdup_printf("%s", ((immediately) ? "true": "false")));
863
864 while(osc_parser->offset < osc_parser->start_offset + osc_parser->packet_size){
865 current_byte = ags_osc_parser_osc_getc(osc_parser);
866
867 if(current_byte == '#'){
868 current = ags_osc_parser_bundle(osc_parser);
869 }else if(current_byte == '/'){
870 current = ags_osc_parser_message(osc_parser);
871 }else{
872 current = NULL;
873
874 g_warning("failed to read bundle or message");
875 }
876
877 if(current != NULL){
878 xmlAddChild(node,
879 current);
880 }
881 }
882
883 return(node);
884 }
885
886 /**
887 * ags_osc_parser_bundle:
888 * @osc_parser: the #AgsOscParser
889 *
890 * Parse OSC bundle.
891 *
892 * Returns: (transfer none): the parsed XML node
893 *
894 * Since: 3.0.0
895 */
896 xmlNode*
ags_osc_parser_bundle(AgsOscParser * osc_parser)897 ags_osc_parser_bundle(AgsOscParser *osc_parser)
898 {
899 xmlNode *node;
900
901 g_return_val_if_fail(AGS_IS_OSC_PARSER(osc_parser), NULL);
902
903 g_object_ref((GObject *) osc_parser);
904 g_signal_emit(G_OBJECT(osc_parser),
905 osc_parser_signals[BUNDLE], 0,
906 &node);
907 g_object_unref((GObject *) osc_parser);
908
909 return(node);
910 }
911
912 xmlNode*
ags_osc_parser_real_message(AgsOscParser * osc_parser)913 ags_osc_parser_real_message(AgsOscParser *osc_parser)
914 {
915 xmlNode *node, *current;
916
917 gchar *address_pattern;
918 gchar *type_tag;
919 gchar *str;
920 gchar current_byte;
921
922 node = xmlNewNode(NULL,
923 "osc-message");
924
925 str = ags_osc_parser_read_text(osc_parser,
926 -1);
927
928 address_pattern = g_strdup_printf("/%s", str);
929 g_free(str);
930
931 xmlNewProp(node,
932 "address-pattern",
933 address_pattern);
934
935 current_byte = ags_osc_parser_osc_getc(osc_parser);
936
937 if(current_byte != ','){
938 unsigned char *blob;
939
940 char str[4];
941 gint32 value;
942 guint i;
943
944 /* no type tag - provide blob */
945 str[0] = (char) 0xff & current_byte;
946 str[1] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
947 str[2] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
948 str[3] = (char) 0xff & ags_osc_parser_osc_getc(osc_parser);
949
950 value = (str[0] & 0xff);
951 value = (value<<8) + (str[1] & 0xff);
952 value = (value<<8) + (str[2] & 0xff);
953 value = (value<<8) + (str[3] & 0xff);
954
955 current = xmlNewNode(NULL,
956 "osc-value");
957
958 blob = (unsigned char *) malloc(value * sizeof(unsigned char));
959
960 for(i = 0; i < value; i++){
961 blob[i] = ags_osc_parser_osc_getc(osc_parser);
962 }
963
964 xmlNodeSetContent(current,
965 g_base64_encode(blob,
966 value));
967
968 free(blob);
969
970 xmlAddChild(node,
971 current);
972 }else{
973 gchar *iter;
974
975 /* has got type tag */
976 str = ags_osc_parser_read_text(osc_parser,
977 -1);
978
979 type_tag = g_strdup_printf(",%s", str);
980 g_free(str);
981
982 xmlNewProp(node,
983 "type-tag",
984 type_tag);
985
986 for(iter = type_tag + 1; iter[0] != '\0'; iter++){
987 switch(iter[0]){
988 case AGS_OSC_UTIL_TYPE_TAG_STRING_INT32:
989 case AGS_OSC_UTIL_TYPE_TAG_STRING_FLOAT:
990 case AGS_OSC_UTIL_TYPE_TAG_STRING_STRING:
991 case AGS_OSC_UTIL_TYPE_TAG_STRING_BLOB:
992 case AGS_OSC_UTIL_TYPE_TAG_STRING_INT64:
993 case AGS_OSC_UTIL_TYPE_TAG_STRING_TIMETAG:
994 case AGS_OSC_UTIL_TYPE_TAG_STRING_DOUBLE:
995 case AGS_OSC_UTIL_TYPE_TAG_STRING_SYMBOL:
996 case AGS_OSC_UTIL_TYPE_TAG_STRING_CHAR:
997 case AGS_OSC_UTIL_TYPE_TAG_STRING_RGBA:
998 case AGS_OSC_UTIL_TYPE_TAG_STRING_MIDI:
999 {
1000 current = ags_osc_parser_value(osc_parser,
1001 iter[0]);
1002
1003 if(current != NULL){
1004 xmlAddChild(node,
1005 current);
1006 }
1007 }
1008 break;
1009 case AGS_OSC_UTIL_TYPE_TAG_STRING_TRUE:
1010 case AGS_OSC_UTIL_TYPE_TAG_STRING_FALSE:
1011 case AGS_OSC_UTIL_TYPE_TAG_STRING_INFINITE:
1012 case AGS_OSC_UTIL_TYPE_TAG_STRING_NIL:
1013 case AGS_OSC_UTIL_TYPE_TAG_STRING_ARRAY_START:
1014 case AGS_OSC_UTIL_TYPE_TAG_STRING_ARRAY_END:
1015 break;
1016 default:
1017 {
1018 g_warning("unknown type");
1019 }
1020 }
1021 }
1022 }
1023
1024 return(node);
1025 }
1026
1027 /**
1028 * ags_osc_parser_message:
1029 * @osc_parser: the #AgsOscParser
1030 *
1031 * Parse OSC message.
1032 *
1033 * Returns: (transfer none): the parsed XML node
1034 *
1035 * Since: 3.0.0
1036 */
1037 xmlNode*
ags_osc_parser_message(AgsOscParser * osc_parser)1038 ags_osc_parser_message(AgsOscParser *osc_parser)
1039 {
1040 xmlNode *node;
1041
1042 g_return_val_if_fail(AGS_IS_OSC_PARSER(osc_parser), NULL);
1043
1044 g_object_ref((GObject *) osc_parser);
1045 g_signal_emit(G_OBJECT(osc_parser),
1046 osc_parser_signals[MESSAGE], 0,
1047 &node);
1048 g_object_unref((GObject *) osc_parser);
1049
1050 return(node);
1051 }
1052
1053 xmlNode*
ags_osc_parser_real_value(AgsOscParser * osc_parser,guint v_type)1054 ags_osc_parser_real_value(AgsOscParser *osc_parser,
1055 guint v_type)
1056 {
1057 xmlNode *node;
1058
1059 node = xmlNewNode(NULL,
1060 "osc-value");
1061
1062 switch(v_type){
1063 case AGS_OSC_UTIL_TYPE_TAG_STRING_INT32:
1064 {
1065 xmlNewProp(node,
1066 "int32",
1067 g_strdup_printf("%d", ags_osc_parser_read_gint32(osc_parser)));
1068 }
1069 break;
1070 case AGS_OSC_UTIL_TYPE_TAG_STRING_FLOAT:
1071 {
1072 xmlNewProp(node,
1073 "float",
1074 g_strdup_printf("%f", ags_osc_parser_read_gfloat(osc_parser)));
1075 }
1076 break;
1077 case AGS_OSC_UTIL_TYPE_TAG_STRING_STRING:
1078 {
1079 xmlNewProp(node,
1080 "text",
1081 ags_osc_parser_read_text(osc_parser,
1082 -1));
1083 }
1084 break;
1085 case AGS_OSC_UTIL_TYPE_TAG_STRING_BLOB:
1086 {
1087 unsigned char *blob;
1088
1089 gint32 data_size;
1090 guint i;
1091
1092 data_size = ags_osc_parser_read_gint32(osc_parser);
1093
1094 blob = (unsigned char *) malloc(data_size * sizeof(unsigned char));
1095
1096 for(i = 0; i < data_size; i++){
1097 blob[i] = ags_osc_parser_osc_getc(osc_parser);
1098 }
1099
1100 xmlNodeSetContent(node,
1101 g_base64_encode(blob,
1102 data_size));
1103
1104 free(blob);
1105 }
1106 break;
1107 case AGS_OSC_UTIL_TYPE_TAG_STRING_INT64:
1108 {
1109 xmlNewProp(node,
1110 "int64",
1111 g_strdup_printf("%ld", ags_osc_parser_read_gint64(osc_parser)));
1112 }
1113 break;
1114 case AGS_OSC_UTIL_TYPE_TAG_STRING_TIMETAG:
1115 {
1116 gint32 tv_secs;
1117 gint32 tv_fraction;
1118 gboolean immediately;
1119
1120 tv_secs = ags_osc_parser_read_gint32(osc_parser);
1121 tv_fraction = ags_osc_parser_read_gint32(osc_parser);
1122
1123 immediately = (0x1 & (tv_fraction)) ? TRUE: FALSE;
1124
1125 xmlNewProp(node,
1126 "tv-secs",
1127 g_strdup_printf("%d", tv_secs));
1128
1129 xmlNewProp(node,
1130 "tv-fraction",
1131 g_strdup_printf("%d", tv_fraction));
1132
1133 xmlNewProp(node,
1134 "immediately",
1135 g_strdup_printf("%s", ((immediately) ? "true": "false")));
1136 }
1137 break;
1138 case AGS_OSC_UTIL_TYPE_TAG_STRING_DOUBLE:
1139 {
1140 xmlNewProp(node,
1141 "double",
1142 g_strdup_printf("%f", ags_osc_parser_read_gdouble(osc_parser)));
1143 }
1144 break;
1145 case AGS_OSC_UTIL_TYPE_TAG_STRING_SYMBOL:
1146 {
1147 xmlNewProp(node,
1148 "symbol",
1149 ags_osc_parser_read_text(osc_parser,
1150 -1));
1151 }
1152 break;
1153 case AGS_OSC_UTIL_TYPE_TAG_STRING_CHAR:
1154 {
1155 gint32 c;
1156
1157 c = ags_osc_parser_read_gint32(osc_parser);
1158
1159 xmlNewProp(node,
1160 "char",
1161 g_strdup_printf("%c", c));
1162 }
1163 break;
1164 case AGS_OSC_UTIL_TYPE_TAG_STRING_RGBA:
1165 {
1166 guint8 r, g, b, a;
1167
1168 r = 0xff & (ags_osc_parser_osc_getc(osc_parser));
1169 g = 0xff & (ags_osc_parser_osc_getc(osc_parser));
1170 b = 0xff & (ags_osc_parser_osc_getc(osc_parser));
1171 a = 0xff & (ags_osc_parser_osc_getc(osc_parser));
1172
1173 xmlNewProp(node,
1174 "red",
1175 g_strdup_printf("%u", r));
1176
1177 xmlNewProp(node,
1178 "green",
1179 g_strdup_printf("%u", g));
1180
1181 xmlNewProp(node,
1182 "blue",
1183 g_strdup_printf("%u", b));
1184
1185 xmlNewProp(node,
1186 "alpha",
1187 g_strdup_printf("%u", a));
1188 }
1189 break;
1190 case AGS_OSC_UTIL_TYPE_TAG_STRING_MIDI:
1191 {
1192 guint8 port;
1193 guint8 status_byte;
1194 guint8 data0, data1;
1195
1196 port = 0xff & (ags_osc_parser_osc_getc(osc_parser));
1197 status_byte = 0xff & (ags_osc_parser_osc_getc(osc_parser));
1198 data0 = 0xff & (ags_osc_parser_osc_getc(osc_parser));
1199 data1 = 0xff & (ags_osc_parser_osc_getc(osc_parser));
1200
1201 xmlNewProp(node,
1202 "port",
1203 g_strdup_printf("%u", port));
1204
1205 xmlNewProp(node,
1206 "status-byte",
1207 g_strdup_printf("%u", status_byte));
1208
1209 xmlNewProp(node,
1210 "data0",
1211 g_strdup_printf("%u", data0));
1212
1213 xmlNewProp(node,
1214 "data1",
1215 g_strdup_printf("%u", data1));
1216 }
1217 break;
1218 }
1219
1220 return(node);
1221 }
1222
1223 /**
1224 * ags_osc_parser_value:
1225 * @osc_parser: the #AgsOscParser
1226 * @v_type: value type
1227 *
1228 * Parse OSC value.
1229 *
1230 * Returns: (transfer none): the parsed XML node
1231 *
1232 * Since: 3.0.0
1233 */
1234 xmlNode*
ags_osc_parser_value(AgsOscParser * osc_parser,guint v_type)1235 ags_osc_parser_value(AgsOscParser *osc_parser,
1236 guint v_type)
1237 {
1238 xmlNode *node;
1239
1240 g_return_val_if_fail(AGS_IS_OSC_PARSER(osc_parser), NULL);
1241
1242 g_object_ref((GObject *) osc_parser);
1243 g_signal_emit(G_OBJECT(osc_parser),
1244 osc_parser_signals[VALUE], 0,
1245 v_type,
1246 &node);
1247 g_object_unref((GObject *) osc_parser);
1248
1249 return(node);
1250 }
1251
1252 /**
1253 * ags_osc_parser_new:
1254 *
1255 * Creates a new instance of #AgsOscParser
1256 *
1257 * Returns: the new #AgsOscParser
1258 *
1259 * Since: 3.0.0
1260 */
1261 AgsOscParser*
ags_osc_parser_new()1262 ags_osc_parser_new()
1263 {
1264 AgsOscParser *osc_parser;
1265
1266 osc_parser = (AgsOscParser *) g_object_new(AGS_TYPE_OSC_PARSER,
1267 NULL);
1268
1269 return(osc_parser);
1270 }
1271