ges-launch: Add support for +test-clip
[platform/upstream/gstreamer.git] / ges / ges-structure-parser.c
1 /* GStreamer Editing Services
2  *
3  * Copyright (C) <2015> Mathieu Duponchelle <mathieu.duponchelle@opencreed.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "ges-structure-parser.h"
22
23 #include <ges/ges.h>
24
25 G_DEFINE_TYPE (GESStructureParser, ges_structure_parser, G_TYPE_OBJECT);
26
27 static void
28 ges_structure_parser_init (GESStructureParser * self)
29 {
30 }
31
32 static void
33 _finalize (GObject * self)
34 {
35   GList *tmp;
36
37   for (tmp = ((GESStructureParser *) self)->structures; tmp; tmp = tmp->next) {
38     gst_structure_free (tmp->data);
39   }
40
41   for (tmp = ((GESStructureParser *) self)->wrong_strings; tmp; tmp = tmp->next) {
42     g_free (tmp->data);
43   }
44 }
45
46 static void
47 ges_structure_parser_class_init (GESStructureParserClass * klass)
48 {
49   G_OBJECT_CLASS (klass)->finalize = _finalize;
50 }
51
52 void
53 ges_structure_parser_parse_string (GESStructureParser * self,
54     const gchar * text, gboolean is_symbol)
55 {
56   gchar *new_string = NULL;
57
58   if (self->current_string) {
59     new_string = g_strconcat (self->current_string, text, NULL);
60   } else if (is_symbol) {
61     new_string = g_strdup (text);
62   }
63
64   g_free (self->current_string);
65   self->current_string = new_string;
66 }
67
68 void
69 ges_structure_parser_parse_default (GESStructureParser * self,
70     const gchar * text)
71 {
72   gchar *new_string = NULL;
73
74   if (self->add_comma && self->current_string) {
75     new_string = g_strconcat (self->current_string, ",", text, NULL);
76     g_free (self->current_string);
77     self->current_string = new_string;
78     self->add_comma = FALSE;
79   } else {
80     ges_structure_parser_parse_string (self, text, FALSE);
81   }
82 }
83
84 void
85 ges_structure_parser_parse_whitespace (GESStructureParser * self)
86 {
87   self->add_comma = TRUE;
88 }
89
90 static void
91 _finish_structure (GESStructureParser * self)
92 {
93   if (self->current_string) {
94     GstStructure *structure =
95         gst_structure_new_from_string (self->current_string);
96
97     if (structure == NULL) {
98       GST_ERROR ("Could not parse %s", self->current_string);
99
100       self->wrong_strings = g_list_append (self->wrong_strings,
101           g_strdup (self->current_string));
102
103       return;
104     }
105
106     self->structures = g_list_append (self->structures, structure);
107     g_free (self->current_string);
108     self->current_string = NULL;
109   }
110 }
111
112 void
113 ges_structure_parser_end_of_file (GESStructureParser * self)
114 {
115   _finish_structure (self);
116 }
117
118 void
119 ges_structure_parser_parse_symbol (GESStructureParser * self,
120     const gchar * symbol)
121 {
122   _finish_structure (self);
123
124   while (*symbol == ' ' || *symbol == '+')
125     symbol++;
126
127   self->add_comma = FALSE;
128   if (!g_ascii_strncasecmp (symbol, "clip", 4))
129     ges_structure_parser_parse_string (self, "clip, uri=", TRUE);
130   else if (!g_ascii_strncasecmp (symbol, "test-clip", 9))
131     ges_structure_parser_parse_string (self, "test-clip, pattern=", TRUE);
132   else if (!g_ascii_strncasecmp (symbol, "effect", 6))
133     ges_structure_parser_parse_string (self, "effect, bin-description=", TRUE);
134   else if (!g_ascii_strncasecmp (symbol, "transition", 10))
135     ges_structure_parser_parse_string (self, "transition, type=", TRUE);
136 }
137
138 void
139 ges_structure_parser_parse_setter (GESStructureParser * self,
140     const gchar * setter)
141 {
142   gchar *parsed_setter;
143
144   _finish_structure (self);
145
146   while (*setter == '-' || *setter == ' ')
147     setter++;
148
149   while (*setter != '-')
150     setter++;
151
152   setter++;
153
154   parsed_setter = g_strdup_printf ("set-property, property=%s, value=", setter);
155   self->add_comma = FALSE;
156   ges_structure_parser_parse_string (self, parsed_setter, TRUE);
157   g_free (parsed_setter);
158 }
159
160 GESStructureParser *
161 ges_structure_parser_new (void)
162 {
163   return (g_object_new (GES_TYPE_STRUCTURE_PARSER, NULL));
164 }
165
166 GError *
167 ges_structure_parser_get_error (GESStructureParser * self)
168 {
169   GList *tmp;
170   GError *error = NULL;
171   GString *msg = NULL;
172
173   if (self->wrong_strings == NULL)
174     return NULL;
175
176   msg = g_string_new ("Could not parse: ");
177
178
179   for (tmp = self->wrong_strings; tmp; tmp = tmp->next) {
180     g_string_append_printf (msg, " %s", (gchar *) tmp->data);
181   }
182
183   error = g_error_new_literal (GES_ERROR, 0, msg->str);
184   g_string_free (msg, TRUE);
185
186   GST_ERROR ("BoOOOM ");
187   return error;
188 }