Forget about the canvas patchbay, I'll work that later
[klaudia.git] / fst / fpsparser.c
blobf15e8c323d8b2a4b916835f92bb913951d039bbe
2 #include <glib.h>
3 #include <stdio.h>
4 #include <string.h>
6 #include <fst.h>
8 typedef struct PluginParserState {
9 gsize chunk_size;
10 gsize chunk_pos;
11 gint base64_state;
12 guint base64_save;
13 guchar *chunk_data;
14 FST *fst;
15 } PluginParserState;
17 PluginParserState *pstate_new( FST *fst ) {
18 PluginParserState *retval = g_malloc0( sizeof( PluginParserState ) );
19 retval->fst = fst;
20 return retval;
23 void g_markup_collect_attr( const gchar *element_name,
24 const gchar **attribute_names,
25 const gchar **attribute_values,
26 GError **error,
27 const gchar *attr_name,
28 const gchar **dst )
30 int i;
31 for (i = 0; attribute_names[i]; i++) {
32 if( strcmp( attribute_names[i], attr_name ) )
33 continue;
35 *dst = attribute_values[i];
36 return;
39 // If we are here we didnt find it.
40 g_set_error (error, G_MARKUP_ERROR,
41 G_MARKUP_ERROR_INVALID_CONTENT,
42 "element '%s' requires attribute '%s'",
43 element_name, attr_name);
48 void start_check ( const gchar * element_name,
49 const gchar **attribute_names,
50 const gchar **attribute_values,
51 PluginParserState *pstate,
52 GError **error)
54 const gchar *field_string;
55 const gchar *val_string;
56 char testString[64];
57 int success;
58 FST *fst = pstate->fst;
61 g_markup_collect_attr( element_name, attribute_names, attribute_values, error, "field", &field_string );
62 if( *error != NULL )
63 return;
65 g_markup_collect_attr( element_name, attribute_names, attribute_values, error, "value", &val_string );
66 if( *error != NULL )
67 return;
70 printf( "got check %s = %s\n", field_string, val_string );
72 if( strcmp( field_string, "productString" ) == 0 ) {
73 success = fst_call_dispatcher( fst, effGetProductString, 0, 0, testString, 0 );
75 else if( strcmp( field_string, "effectName" ) == 0 ) {
76 success = fst_call_dispatcher( fst, effGetEffectName, 0, 0, testString, 0 );
78 else if( strcmp( field_string, "vendorString" ) == 0 ) {
79 success = fst_call_dispatcher( fst, effGetVendorString, 0, 0, testString, 0 );
82 if (success == 1) {
83 if (strcmp (testString, val_string) != 0) {
84 g_set_error (error, G_MARKUP_ERROR,
85 G_MARKUP_ERROR_INVALID_CONTENT,
86 "file is for another plugin" );
87 printf ("string mismatch! Plugin has: %s\n", testString);
88 return;
90 } else {
91 g_set_error (error, G_MARKUP_ERROR,
92 G_MARKUP_ERROR_INVALID_CONTENT,
93 "file is for another plugin" );
94 printf ("string mismatch! Plugin has none.\n");
95 return;
100 void start_param ( const gchar * element_name,
101 const gchar **attribute_names,
102 const gchar **attribute_values,
103 PluginParserState *pstate,
104 GError **error)
106 const gchar *index_string;
107 const gchar *val_string;
108 int index;
109 float val;
110 FST *fst = pstate->fst;
112 if( fst->plugin->flags & 32 )
113 return;
115 g_markup_collect_attr( element_name, attribute_names, attribute_values, error, "index", &index_string );
116 if( *error != NULL )
117 return;
119 g_markup_collect_attr( element_name, attribute_names, attribute_values, error, "value", &val_string );
120 if( *error != NULL )
121 return;
123 index = (int) g_ascii_strtoull( index_string, NULL, 10 );
124 val = (float) g_ascii_strtod( val_string, NULL );
126 pthread_mutex_lock( &fst->lock );
127 fst->plugin->setParameter( fst->plugin, index, val );
128 pthread_mutex_unlock( &fst->lock );
131 void start_chunk ( const gchar * element_name,
132 const gchar **attribute_names,
133 const gchar **attribute_values,
134 PluginParserState *pstate,
135 GError **error)
137 const gchar *size_string;
138 FST *fst = pstate->fst;
140 if( ! (fst->plugin->flags & 32) ) {
142 return;
144 g_markup_collect_attr( element_name, attribute_names, attribute_values, error, "size", &size_string );
146 if( *error != NULL )
147 return;
149 pstate->chunk_size = g_ascii_strtoull( size_string, NULL, 10 );
150 if( pstate->chunk_size == 0 ) {
151 // TODO: set error.
152 g_set_error (error, G_MARKUP_ERROR,
153 G_MARKUP_ERROR_INVALID_CONTENT,
154 "chunk size is 0 or invalid" );
155 return;
158 pstate->chunk_data = g_malloc0( pstate->chunk_size );
159 if( pstate->chunk_data == NULL ) {
160 g_set_error (error, G_MARKUP_ERROR,
161 G_MARKUP_ERROR_INVALID_CONTENT,
162 "cant allocate memory" );
163 return;
166 pstate->base64_state = 0;
167 pstate->base64_save = 0;
170 void end_chunk( PluginParserState *pstate,
171 GError **error)
173 // Set Chunk to plug here.
174 FST *fst = pstate->fst;
175 fst_call_dispatcher( fst, 24, 0, pstate->chunk_size, pstate->chunk_data, 0 );
177 g_free( pstate->chunk_data );
178 pstate->chunk_data = NULL;
179 pstate->chunk_size = 0;
183 void start_element (GMarkupParseContext *context,
184 const gchar *element_name,
185 const gchar **attribute_names,
186 const gchar **attribute_values,
187 gpointer user_data,
188 GError **error)
190 PluginParserState *pstate = (PluginParserState *) user_data;
192 if( strcmp( element_name, "chunk" ) == 0 ) {
193 start_chunk( element_name, attribute_names, attribute_values, pstate, error );
195 if( strcmp( element_name, "check" ) == 0 ) {
196 start_check( element_name, attribute_names, attribute_values, pstate, error );
198 if( strcmp( element_name, "param" ) == 0 ) {
199 start_param( element_name, attribute_names, attribute_values, pstate, error );
203 /* Called for close tags </foo> */
204 void end_element (GMarkupParseContext *context,
205 const gchar *element_name,
206 gpointer user_data,
207 GError **error)
209 if( strcmp( element_name, "chunk" )==0 ) {
210 end_chunk( user_data, error );
214 /* Called for character data */
215 /* text is not nul-terminated */
216 void mytext (GMarkupParseContext *context,
217 const gchar *text,
218 gsize text_len,
219 gpointer user_data,
220 GError **error)
222 PluginParserState *pstate = (PluginParserState *) user_data;
223 if( strcmp( g_markup_parse_context_get_element( context ), "chunk" ) == 0 )
225 gsize num_bytes = g_base64_decode_step( text, text_len, pstate->chunk_data + pstate->chunk_pos, &pstate->base64_state, &pstate->base64_save );
226 pstate->chunk_pos += num_bytes;
230 #define BUFFER_SIZE 256
232 int fst_load_state( FST *fst, char *filename )
234 char buf[BUFFER_SIZE];
235 int i;
236 GError *err = NULL;
238 GIOChannel *chan = g_io_channel_new_file( filename, "r", &err );
240 GMarkupParser parser = { NULL, NULL, NULL, NULL, NULL };
241 parser.start_element = start_element;
242 parser.end_element = end_element;
243 parser.text = mytext;
245 PluginParserState *pstate = pstate_new( fst );
248 GMarkupParseContext *context = g_markup_parse_context_new( &parser, 0, pstate, NULL );
250 while(1) {
251 gsize bytes;
252 GIOStatus status = g_io_channel_read_chars( chan, buf, BUFFER_SIZE, &bytes, &err );
253 if( status == G_IO_STATUS_ERROR )
254 break;
255 if( status == G_IO_STATUS_EOF )
256 break;
258 g_markup_parse_context_parse( context, buf, bytes, &err );
259 if( err != NULL )
260 break;
263 if( err != NULL )
264 g_markup_parse_context_end_parse( context, &err );
265 g_markup_parse_context_free( context );
266 if( err != NULL )
267 return 0;
269 return 1;