8 typedef struct PluginParserState
{
17 PluginParserState
*pstate_new( FST
*fst
) {
18 PluginParserState
*retval
= g_malloc0( sizeof( PluginParserState
) );
23 void g_markup_collect_attr( const gchar
*element_name
,
24 const gchar
**attribute_names
,
25 const gchar
**attribute_values
,
27 const gchar
*attr_name
,
31 for (i
= 0; attribute_names
[i
]; i
++) {
32 if( strcmp( attribute_names
[i
], attr_name
) )
35 *dst
= attribute_values
[i
];
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
,
54 const gchar
*field_string
;
55 const gchar
*val_string
;
58 FST
*fst
= pstate
->fst
;
61 g_markup_collect_attr( element_name
, attribute_names
, attribute_values
, error
, "field", &field_string
);
65 g_markup_collect_attr( element_name
, attribute_names
, attribute_values
, error
, "value", &val_string
);
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 );
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
);
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");
100 void start_param ( const gchar
* element_name
,
101 const gchar
**attribute_names
,
102 const gchar
**attribute_values
,
103 PluginParserState
*pstate
,
106 const gchar
*index_string
;
107 const gchar
*val_string
;
110 FST
*fst
= pstate
->fst
;
112 if( fst
->plugin
->flags
& 32 )
115 g_markup_collect_attr( element_name
, attribute_names
, attribute_values
, error
, "index", &index_string
);
119 g_markup_collect_attr( element_name
, attribute_names
, attribute_values
, error
, "value", &val_string
);
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
,
137 const gchar
*size_string
;
138 FST
*fst
= pstate
->fst
;
140 if( ! (fst
->plugin
->flags
& 32) ) {
144 g_markup_collect_attr( element_name
, attribute_names
, attribute_values
, error
, "size", &size_string
);
149 pstate
->chunk_size
= g_ascii_strtoull( size_string
, NULL
, 10 );
150 if( pstate
->chunk_size
== 0 ) {
152 g_set_error (error
, G_MARKUP_ERROR
,
153 G_MARKUP_ERROR_INVALID_CONTENT
,
154 "chunk size is 0 or invalid" );
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" );
166 pstate
->base64_state
= 0;
167 pstate
->base64_save
= 0;
170 void end_chunk( PluginParserState
*pstate
,
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
,
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
,
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
,
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
];
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
);
252 GIOStatus status
= g_io_channel_read_chars( chan
, buf
, BUFFER_SIZE
, &bytes
, &err
);
253 if( status
== G_IO_STATUS_ERROR
)
255 if( status
== G_IO_STATUS_EOF
)
258 g_markup_parse_context_parse( context
, buf
, bytes
, &err
);
264 g_markup_parse_context_end_parse( context
, &err
);
265 g_markup_parse_context_free( context
);