8499f440b8e05a9bbfba46dee4631c8c2d8d56d0
[melted] / src / valerie / valerie.c
1 /*
2 * valerie.c -- High Level Client API for miracle
3 * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
4 * Author: Charles Yates <charles.yates@pandora.be>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library 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 GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 /* System header files */
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdarg.h>
26
27 /* Application header files */
28 #include "valerie.h"
29 #include "valerie_tokeniser.h"
30 #include "valerie_util.h"
31
32 /** Initialise the valerie structure.
33 */
34
35 valerie valerie_init( valerie_parser parser )
36 {
37 valerie this = malloc( sizeof( valerie_t ) );
38 if ( this != NULL )
39 {
40 memset( this, 0, sizeof( valerie_t ) );
41 this->parser = parser;
42 }
43 return this;
44 }
45
46 /** Set the response structure associated to the last command.
47 */
48
49 static void valerie_set_last_response( valerie this, valerie_response response )
50 {
51 if ( this != NULL )
52 {
53 if ( this->last_response != NULL )
54 valerie_response_close( this->last_response );
55 this->last_response = response;
56 }
57 }
58
59 /** Connect to the parser.
60 */
61
62 valerie_error_code valerie_connect( valerie this )
63 {
64 valerie_error_code error = valerie_server_unavailable;
65 valerie_response response = valerie_parser_connect( this->parser );
66 if ( response != NULL )
67 {
68 valerie_set_last_response( this, response );
69 if ( valerie_response_get_error_code( response ) == 100 )
70 error = valerie_ok;
71 }
72 return error;
73 }
74
75 /** Interpret a non-context sensitive error code.
76 */
77
78 static valerie_error_code valerie_get_error_code( valerie this, valerie_response response )
79 {
80 valerie_error_code error = valerie_server_unavailable;
81 switch( valerie_response_get_error_code( response ) )
82 {
83 case -1:
84 error = valerie_server_unavailable;
85 break;
86 case -2:
87 error = valerie_no_response;
88 break;
89 case 200:
90 case 201:
91 case 202:
92 error = valerie_ok;
93 break;
94 case 400:
95 error = valerie_invalid_command;
96 break;
97 case 401:
98 error = valerie_server_timeout;
99 break;
100 case 402:
101 error = valerie_missing_argument;
102 break;
103 case 403:
104 error = valerie_unit_unavailable;
105 break;
106 case 404:
107 error = valerie_invalid_file;
108 break;
109 default:
110 case 500:
111 error = valerie_unknown_error;
112 break;
113 }
114 return error;
115 }
116
117 /** Execute a command.
118 */
119
120 valerie_error_code valerie_execute( valerie this, size_t size, char *format, ... )
121 {
122 valerie_error_code error = valerie_server_unavailable;
123 char *command = malloc( size );
124 if ( this != NULL && command != NULL )
125 {
126 va_list list;
127 va_start( list, format );
128 if ( vsnprintf( command, size, format, list ) != 0 )
129 {
130 valerie_response response = valerie_parser_execute( this->parser, command );
131 valerie_set_last_response( this, response );
132 error = valerie_get_error_code( this, response );
133 }
134 else
135 {
136 error = valerie_invalid_command;
137 }
138 va_end( list );
139 }
140 else
141 {
142 error = valerie_malloc_failed;
143 }
144 free( command );
145 return error;
146 }
147
148 /** Execute a command.
149 */
150
151 valerie_error_code valerie_push( valerie this, mlt_service service, size_t size, char *format, ... )
152 {
153 valerie_error_code error = valerie_server_unavailable;
154 char *command = malloc( size );
155 if ( this != NULL && command != NULL )
156 {
157 va_list list;
158 va_start( list, format );
159 if ( vsnprintf( command, size, format, list ) != 0 )
160 {
161 valerie_response response = valerie_parser_push( this->parser, command, service );
162 valerie_set_last_response( this, response );
163 error = valerie_get_error_code( this, response );
164 }
165 else
166 {
167 error = valerie_invalid_command;
168 }
169 va_end( list );
170 }
171 else
172 {
173 error = valerie_malloc_failed;
174 }
175 free( command );
176 return error;
177 }
178
179 /** Set a global property.
180 */
181
182 valerie_error_code valerie_set( valerie this, char *property, char *value )
183 {
184 return valerie_execute( this, 1024, "SET %s=%s", property, value );
185 }
186
187 /** Get a global property.
188 */
189
190 valerie_error_code valerie_get( valerie this, char *property, char *value, int length )
191 {
192 valerie_error_code error = valerie_execute( this, 1024, "GET %s", property );
193 if ( error == valerie_ok )
194 {
195 valerie_response response = valerie_get_last_response( this );
196 strncpy( value, valerie_response_get_line( response, 1 ), length );
197 }
198 return error;
199 }
200
201 /** Run a script.
202 */
203
204 valerie_error_code valerie_run( valerie this, char *file )
205 {
206 return valerie_execute( this, 10240, "RUN \"%s\"", file );
207 }
208
209 /** Add a unit.
210 */
211
212 valerie_error_code valerie_unit_add( valerie this, char *guid, int *unit )
213 {
214 valerie_error_code error = valerie_execute( this, 1024, "UADD %s", guid );
215 if ( error == valerie_ok )
216 {
217 int length = valerie_response_count( this->last_response );
218 char *line = valerie_response_get_line( this->last_response, length - 1 );
219 if ( line == NULL || sscanf( line, "U%d", unit ) != 1 )
220 error = valerie_unit_creation_failed;
221 }
222 else
223 {
224 if ( error == valerie_unknown_error )
225 error = valerie_unit_creation_failed;
226 }
227 return error;
228 }
229
230 /** Load a file on the specified unit.
231 */
232
233 valerie_error_code valerie_unit_load( valerie this, int unit, char *file )
234 {
235 return valerie_execute( this, 10240, "LOAD U%d \"%s\"", unit, file );
236 }
237
238 static void valerie_interpret_clip_offset( char *output, valerie_clip_offset offset, int clip )
239 {
240 switch( offset )
241 {
242 case valerie_absolute:
243 sprintf( output, "%d", clip );
244 break;
245 case valerie_relative:
246 if ( clip < 0 )
247 sprintf( output, "%d", clip );
248 else
249 sprintf( output, "+%d", clip );
250 break;
251 }
252 }
253
254 /** Load a file on the specified unit with the specified in/out points.
255 */
256
257 valerie_error_code valerie_unit_load_clipped( valerie this, int unit, char *file, int32_t in, int32_t out )
258 {
259 return valerie_execute( this, 10240, "LOAD U%d \"%s\" %d %d", unit, file, in, out );
260 }
261
262 /** Load a file on the specified unit at the end of the current pump.
263 */
264
265 valerie_error_code valerie_unit_load_back( valerie this, int unit, char *file )
266 {
267 return valerie_execute( this, 10240, "LOAD U%d \"!%s\"", unit, file );
268 }
269
270 /** Load a file on the specified unit at the end of the pump with the specified in/out points.
271 */
272
273 valerie_error_code valerie_unit_load_back_clipped( valerie this, int unit, char *file, int32_t in, int32_t out )
274 {
275 return valerie_execute( this, 10240, "LOAD U%d \"!%s\" %d %d", unit, file, in, out );
276 }
277
278 /** Append a file on the specified unit.
279 */
280
281 valerie_error_code valerie_unit_append( valerie this, int unit, char *file, int32_t in, int32_t out )
282 {
283 return valerie_execute( this, 10240, "APND U%d \"%s\" %d %d", unit, file, in, out );
284 }
285
286 /** Push a service on to a unit.
287 */
288
289 valerie_error_code valerie_unit_push( valerie this, int unit, char *command, mlt_service service )
290 {
291 return valerie_push( this, service, 10240, "PUSH U%d %s", unit, command );
292 }
293
294 /** Clean the unit - this function removes all but the currently playing clip.
295 */
296
297 valerie_error_code valerie_unit_clean( valerie this, int unit )
298 {
299 return valerie_execute( this, 1024, "CLEAN U%d", unit );
300 }
301
302 /** Clear the unit - this function removes all clips.
303 */
304
305 valerie_error_code valerie_unit_clear( valerie this, int unit )
306 {
307 return valerie_execute( this, 1024, "CLEAR U%d", unit );
308 }
309
310 /** Move clips on the units playlist.
311 */
312
313 valerie_error_code valerie_unit_clip_move( valerie this, int unit, valerie_clip_offset src_offset, int src, valerie_clip_offset dest_offset, int dest )
314 {
315 char temp1[ 100 ];
316 char temp2[ 100 ];
317 valerie_interpret_clip_offset( temp1, src_offset, src );
318 valerie_interpret_clip_offset( temp2, dest_offset, dest );
319 return valerie_execute( this, 1024, "MOVE U%d %s %s", unit, temp1, temp2 );
320 }
321
322 /** Remove clip at the specified position.
323 */
324
325 valerie_error_code valerie_unit_clip_remove( valerie this, int unit, valerie_clip_offset offset, int clip )
326 {
327 char temp[ 100 ];
328 valerie_interpret_clip_offset( temp, offset, clip );
329 return valerie_execute( this, 1024, "REMOVE U%d %s", unit, temp );
330 }
331
332 /** Remove the currently playing clip.
333 */
334
335 valerie_error_code valerie_unit_remove_current_clip( valerie this, int unit )
336 {
337 return valerie_execute( this, 1024, "REMOVE U%d", unit );
338 }
339
340 /** Insert clip at the specified position.
341 */
342
343 valerie_error_code valerie_unit_clip_insert( valerie this, int unit, valerie_clip_offset offset, int clip, char *file, int32_t in, int32_t out )
344 {
345 char temp[ 100 ];
346 valerie_interpret_clip_offset( temp, offset, clip );
347 return valerie_execute( this, 1024, "INSERT U%d \"%s\" %s %d %d", unit, file, temp, in, out );
348 }
349
350 /** Play the unit at normal speed.
351 */
352
353 valerie_error_code valerie_unit_play( valerie this, int unit )
354 {
355 return valerie_execute( this, 1024, "PLAY U%d 1000", unit );
356 }
357
358 /** Play the unit at specified speed.
359 */
360
361 valerie_error_code valerie_unit_play_at_speed( valerie this, int unit, int speed )
362 {
363 return valerie_execute( this, 10240, "PLAY U%d %d", unit, speed );
364 }
365
366 /** Stop playback on the specified unit.
367 */
368
369 valerie_error_code valerie_unit_stop( valerie this, int unit )
370 {
371 return valerie_execute( this, 1024, "STOP U%d", unit );
372 }
373
374 /** Pause playback on the specified unit.
375 */
376
377 valerie_error_code valerie_unit_pause( valerie this, int unit )
378 {
379 return valerie_execute( this, 1024, "PAUSE U%d", unit );
380 }
381
382 /** Rewind the specified unit.
383 */
384
385 valerie_error_code valerie_unit_rewind( valerie this, int unit )
386 {
387 return valerie_execute( this, 1024, "REW U%d", unit );
388 }
389
390 /** Fast forward the specified unit.
391 */
392
393 valerie_error_code valerie_unit_fast_forward( valerie this, int unit )
394 {
395 return valerie_execute( this, 1024, "FF U%d", unit );
396 }
397
398 /** Step by the number of frames on the specified unit.
399 */
400
401 valerie_error_code valerie_unit_step( valerie this, int unit, int32_t step )
402 {
403 return valerie_execute( this, 1024, "STEP U%d %d", unit, step );
404 }
405
406 /** Goto the specified frame on the specified unit.
407 */
408
409 valerie_error_code valerie_unit_goto( valerie this, int unit, int32_t position )
410 {
411 return valerie_execute( this, 1024, "GOTO U%d %d", unit, position );
412 }
413
414 /** Goto the specified frame in the clip on the specified unit.
415 */
416
417 valerie_error_code valerie_unit_clip_goto( valerie this, int unit, valerie_clip_offset offset, int clip, int32_t position )
418 {
419 char temp[ 100 ];
420 valerie_interpret_clip_offset( temp, offset, clip );
421 return valerie_execute( this, 1024, "GOTO U%d %d %s", unit, position, temp );
422 }
423
424 /** Set the in point of the loaded file on the specified unit.
425 */
426
427 valerie_error_code valerie_unit_set_in( valerie this, int unit, int32_t in )
428 {
429 return valerie_execute( this, 1024, "SIN U%d %d", unit, in );
430 }
431
432 /** Set the in point of the clip on the specified unit.
433 */
434
435 valerie_error_code valerie_unit_clip_set_in( valerie this, int unit, valerie_clip_offset offset, int clip, int32_t in )
436 {
437 char temp[ 100 ];
438 valerie_interpret_clip_offset( temp, offset, clip );
439 return valerie_execute( this, 1024, "SIN U%d %d %s", unit, in, temp );
440 }
441
442 /** Set the out point of the loaded file on the specified unit.
443 */
444
445 valerie_error_code valerie_unit_set_out( valerie this, int unit, int32_t out )
446 {
447 return valerie_execute( this, 1024, "SOUT U%d %d", unit, out );
448 }
449
450 /** Set the out point of the clip on the specified unit.
451 */
452
453 valerie_error_code valerie_unit_clip_set_out( valerie this, int unit, valerie_clip_offset offset, int clip, int32_t in )
454 {
455 char temp[ 100 ];
456 valerie_interpret_clip_offset( temp, offset, clip );
457 return valerie_execute( this, 1024, "SOUT U%d %d %s", unit, in, temp );
458 }
459
460 /** Clear the in point of the loaded file on the specified unit.
461 */
462
463 valerie_error_code valerie_unit_clear_in( valerie this, int unit )
464 {
465 return valerie_execute( this, 1024, "SIN U%d -1", unit );
466 }
467
468 /** Clear the out point of the loaded file on the specified unit.
469 */
470
471 valerie_error_code valerie_unit_clear_out( valerie this, int unit )
472 {
473 return valerie_execute( this, 1024, "SOUT U%d -1", unit );
474 }
475
476 /** Clear the in and out points on the loaded file on the specified unit.
477 */
478
479 valerie_error_code valerie_unit_clear_in_out( valerie this, int unit )
480 {
481 valerie_error_code error = valerie_unit_clear_out( this, unit );
482 if ( error == valerie_ok )
483 error = valerie_unit_clear_in( this, unit );
484 return error;
485 }
486
487 /** Set a unit configuration property.
488 */
489
490 valerie_error_code valerie_unit_set( valerie this, int unit, char *name, char *value )
491 {
492 return valerie_execute( this, 1024, "USET U%d %s=%s", unit, name, value );
493 }
494
495 /** Get a unit configuration property.
496 */
497
498 valerie_error_code valerie_unit_get( valerie this, int unit, char *name )
499 {
500 return valerie_execute( this, 1024, "UGET U%d %s", unit, name );
501 }
502
503 /** Get a units status.
504 */
505
506 valerie_error_code valerie_unit_status( valerie this, int unit, valerie_status status )
507 {
508 valerie_error_code error = valerie_execute( this, 1024, "USTA U%d", unit );
509 int error_code = valerie_response_get_error_code( this->last_response );
510
511 memset( status, 0, sizeof( valerie_status_t ) );
512 status->unit = unit;
513 if ( error_code == 202 && valerie_response_count( this->last_response ) == 2 )
514 valerie_status_parse( status, valerie_response_get_line( this->last_response, 1 ) );
515 else if ( error_code == 403 )
516 status->status = unit_undefined;
517
518 return error;
519 }
520
521 /** Transfer the current settings of unit src to unit dest.
522 */
523
524 valerie_error_code valerie_unit_transfer( valerie this, int src, int dest )
525 {
526 return valerie_execute( this, 1024, "XFER U%d U%d", src, dest );
527 }
528
529 /** Obtain the parsers notifier.
530 */
531
532 valerie_notifier valerie_get_notifier( valerie this )
533 {
534 if ( this != NULL )
535 return valerie_parser_get_notifier( this->parser );
536 else
537 return NULL;
538 }
539
540 /** List the contents of the specified directory.
541 */
542
543 valerie_dir valerie_dir_init( valerie this, char *directory )
544 {
545 valerie_dir dir = malloc( sizeof( valerie_dir_t ) );
546 if ( dir != NULL )
547 {
548 memset( dir, 0, sizeof( valerie_dir_t ) );
549 dir->directory = strdup( directory );
550 dir->response = valerie_parser_executef( this->parser, "CLS \"%s\"", directory );
551 }
552 return dir;
553 }
554
555 /** Return the error code associated to the dir.
556 */
557
558 valerie_error_code valerie_dir_get_error_code( valerie_dir dir )
559 {
560 if ( dir != NULL )
561 return valerie_get_error_code( NULL, dir->response );
562 else
563 return valerie_malloc_failed;
564 }
565
566 /** Get a particular file entry in the directory.
567 */
568
569 valerie_error_code valerie_dir_get( valerie_dir dir, int index, valerie_dir_entry entry )
570 {
571 valerie_error_code error = valerie_ok;
572 memset( entry, 0, sizeof( valerie_dir_entry_t ) );
573 if ( index < valerie_dir_count( dir ) )
574 {
575 char *line = valerie_response_get_line( dir->response, index + 1 );
576 valerie_tokeniser tokeniser = valerie_tokeniser_init( );
577 valerie_tokeniser_parse_new( tokeniser, line, " " );
578
579 if ( valerie_tokeniser_count( tokeniser ) > 0 )
580 {
581 valerie_util_strip( valerie_tokeniser_get_string( tokeniser, 0 ), '\"' );
582 strcpy( entry->full, dir->directory );
583 if ( entry->full[ strlen( entry->full ) - 1 ] != '/' )
584 strcat( entry->full, "/" );
585 strcpy( entry->name, valerie_tokeniser_get_string( tokeniser, 0 ) );
586 strcat( entry->full, entry->name );
587
588 switch ( valerie_tokeniser_count( tokeniser ) )
589 {
590 case 1:
591 entry->dir = 1;
592 break;
593 case 2:
594 entry->size = strtoull( valerie_tokeniser_get_string( tokeniser, 1 ), NULL, 10 );
595 break;
596 default:
597 error = valerie_invalid_file;
598 break;
599 }
600 }
601 valerie_tokeniser_close( tokeniser );
602 }
603 return error;
604 }
605
606 /** Get the number of entries in the directory
607 */
608
609 int valerie_dir_count( valerie_dir dir )
610 {
611 if ( dir != NULL && valerie_response_count( dir->response ) >= 2 )
612 return valerie_response_count( dir->response ) - 2;
613 else
614 return -1;
615 }
616
617 /** Close the directory structure.
618 */
619
620 void valerie_dir_close( valerie_dir dir )
621 {
622 if ( dir != NULL )
623 {
624 free( dir->directory );
625 valerie_response_close( dir->response );
626 free( dir );
627 }
628 }
629
630 /** List the playlist of the specified unit.
631 */
632
633 valerie_list valerie_list_init( valerie this, int unit )
634 {
635 valerie_list list = calloc( 1, sizeof( valerie_list_t ) );
636 if ( list != NULL )
637 {
638 list->response = valerie_parser_executef( this->parser, "LIST U%d", unit );
639 if ( valerie_response_count( list->response ) >= 2 )
640 list->generation = atoi( valerie_response_get_line( list->response, 1 ) );
641 }
642 return list;
643 }
644
645 /** Return the error code associated to the list.
646 */
647
648 valerie_error_code valerie_list_get_error_code( valerie_list list )
649 {
650 if ( list != NULL )
651 return valerie_get_error_code( NULL, list->response );
652 else
653 return valerie_malloc_failed;
654 }
655
656 /** Get a particular file entry in the list.
657 */
658
659 valerie_error_code valerie_list_get( valerie_list list, int index, valerie_list_entry entry )
660 {
661 valerie_error_code error = valerie_ok;
662 memset( entry, 0, sizeof( valerie_list_entry_t ) );
663 if ( index < valerie_list_count( list ) )
664 {
665 char *line = valerie_response_get_line( list->response, index + 2 );
666 valerie_tokeniser tokeniser = valerie_tokeniser_init( );
667 valerie_tokeniser_parse_new( tokeniser, line, " " );
668
669 if ( valerie_tokeniser_count( tokeniser ) > 0 )
670 {
671 entry->clip = atoi( valerie_tokeniser_get_string( tokeniser, 0 ) );
672 valerie_util_strip( valerie_tokeniser_get_string( tokeniser, 1 ), '\"' );
673 strcpy( entry->full, valerie_tokeniser_get_string( tokeniser, 1 ) );
674 entry->in = atol( valerie_tokeniser_get_string( tokeniser, 2 ) );
675 entry->out = atol( valerie_tokeniser_get_string( tokeniser, 3 ) );
676 entry->max = atol( valerie_tokeniser_get_string( tokeniser, 4 ) );
677 entry->size = atol( valerie_tokeniser_get_string( tokeniser, 5 ) );
678 entry->fps = atof( valerie_tokeniser_get_string( tokeniser, 6 ) );
679 }
680 valerie_tokeniser_close( tokeniser );
681 }
682 return error;
683 }
684
685 /** Get the number of entries in the list
686 */
687
688 int valerie_list_count( valerie_list list )
689 {
690 if ( list != NULL && valerie_response_count( list->response ) >= 3 )
691 return valerie_response_count( list->response ) - 3;
692 else
693 return -1;
694 }
695
696 /** Close the list structure.
697 */
698
699 void valerie_list_close( valerie_list list )
700 {
701 if ( list != NULL )
702 {
703 valerie_response_close( list->response );
704 free( list );
705 }
706 }
707
708 /** List the currently connected nodes.
709 */
710
711 valerie_nodes valerie_nodes_init( valerie this )
712 {
713 valerie_nodes nodes = malloc( sizeof( valerie_nodes_t ) );
714 if ( nodes != NULL )
715 {
716 memset( nodes, 0, sizeof( valerie_nodes_t ) );
717 nodes->response = valerie_parser_executef( this->parser, "NLS" );
718 }
719 return nodes;
720 }
721
722 /** Return the error code associated to the nodes list.
723 */
724
725 valerie_error_code valerie_nodes_get_error_code( valerie_nodes nodes )
726 {
727 if ( nodes != NULL )
728 return valerie_get_error_code( NULL, nodes->response );
729 else
730 return valerie_malloc_failed;
731 }
732
733 /** Get a particular node entry.
734 */
735
736 valerie_error_code valerie_nodes_get( valerie_nodes nodes, int index, valerie_node_entry entry )
737 {
738 valerie_error_code error = valerie_ok;
739 memset( entry, 0, sizeof( valerie_node_entry_t ) );
740 if ( index < valerie_nodes_count( nodes ) )
741 {
742 char *line = valerie_response_get_line( nodes->response, index + 1 );
743 valerie_tokeniser tokeniser = valerie_tokeniser_init( );
744 valerie_tokeniser_parse_new( tokeniser, line, " " );
745
746 if ( valerie_tokeniser_count( tokeniser ) == 3 )
747 {
748 entry->node = atoi( valerie_tokeniser_get_string( tokeniser, 0 ) );
749 strncpy( entry->guid, valerie_tokeniser_get_string( tokeniser, 1 ), sizeof( entry->guid ) );
750 valerie_util_strip( valerie_tokeniser_get_string( tokeniser, 2 ), '\"' );
751 strncpy( entry->name, valerie_tokeniser_get_string( tokeniser, 2 ), sizeof( entry->name ) );
752 }
753
754 valerie_tokeniser_close( tokeniser );
755 }
756 return error;
757 }
758
759 /** Get the number of nodes
760 */
761
762 int valerie_nodes_count( valerie_nodes nodes )
763 {
764 if ( nodes != NULL && valerie_response_count( nodes->response ) >= 2 )
765 return valerie_response_count( nodes->response ) - 2;
766 else
767 return -1;
768 }
769
770 /** Close the nodes structure.
771 */
772
773 void valerie_nodes_close( valerie_nodes nodes )
774 {
775 if ( nodes != NULL )
776 {
777 valerie_response_close( nodes->response );
778 free( nodes );
779 }
780 }
781
782 /** List the currently defined units.
783 */
784
785 valerie_units valerie_units_init( valerie this )
786 {
787 valerie_units units = malloc( sizeof( valerie_units_t ) );
788 if ( units != NULL )
789 {
790 memset( units, 0, sizeof( valerie_units_t ) );
791 units->response = valerie_parser_executef( this->parser, "ULS" );
792 }
793 return units;
794 }
795
796 /** Return the error code associated to the nodes list.
797 */
798
799 valerie_error_code valerie_units_get_error_code( valerie_units units )
800 {
801 if ( units != NULL )
802 return valerie_get_error_code( NULL, units->response );
803 else
804 return valerie_malloc_failed;
805 }
806
807 /** Get a particular unit entry.
808 */
809
810 valerie_error_code valerie_units_get( valerie_units units, int index, valerie_unit_entry entry )
811 {
812 valerie_error_code error = valerie_ok;
813 memset( entry, 0, sizeof( valerie_unit_entry_t ) );
814 if ( index < valerie_units_count( units ) )
815 {
816 char *line = valerie_response_get_line( units->response, index + 1 );
817 valerie_tokeniser tokeniser = valerie_tokeniser_init( );
818 valerie_tokeniser_parse_new( tokeniser, line, " " );
819
820 if ( valerie_tokeniser_count( tokeniser ) == 4 )
821 {
822 entry->unit = atoi( valerie_tokeniser_get_string( tokeniser, 0 ) + 1 );
823 entry->node = atoi( valerie_tokeniser_get_string( tokeniser, 1 ) );
824 strncpy( entry->guid, valerie_tokeniser_get_string( tokeniser, 2 ), sizeof( entry->guid ) );
825 entry->online = atoi( valerie_tokeniser_get_string( tokeniser, 3 ) );
826 }
827
828 valerie_tokeniser_close( tokeniser );
829 }
830 return error;
831 }
832
833 /** Get the number of units
834 */
835
836 int valerie_units_count( valerie_units units )
837 {
838 if ( units != NULL && valerie_response_count( units->response ) >= 2 )
839 return valerie_response_count( units->response ) - 2;
840 else
841 return -1;
842 }
843
844 /** Close the units structure.
845 */
846
847 void valerie_units_close( valerie_units units )
848 {
849 if ( units != NULL )
850 {
851 valerie_response_close( units->response );
852 free( units );
853 }
854 }
855
856 /** Get the response of the last command executed.
857 */
858
859 valerie_response valerie_get_last_response( valerie this )
860 {
861 return this->last_response;
862 }
863
864 /** Obtain a printable message associated to the error code provided.
865 */
866
867 char *valerie_error_description( valerie_error_code error )
868 {
869 char *msg = "Unrecognised error";
870 switch( error )
871 {
872 case valerie_ok:
873 msg = "OK";
874 break;
875 case valerie_malloc_failed:
876 msg = "Memory allocation error";
877 break;
878 case valerie_unknown_error:
879 msg = "Unknown error";
880 break;
881 case valerie_no_response:
882 msg = "No response obtained";
883 break;
884 case valerie_invalid_command:
885 msg = "Invalid command";
886 break;
887 case valerie_server_timeout:
888 msg = "Communications with server timed out";
889 break;
890 case valerie_missing_argument:
891 msg = "Missing argument";
892 break;
893 case valerie_server_unavailable:
894 msg = "Unable to communicate with server";
895 break;
896 case valerie_unit_creation_failed:
897 msg = "Unit creation failed";
898 break;
899 case valerie_unit_unavailable:
900 msg = "Unit unavailable";
901 break;
902 case valerie_invalid_file:
903 msg = "Invalid file";
904 break;
905 case valerie_invalid_position:
906 msg = "Invalid position";
907 break;
908 }
909 return msg;
910 }
911
912 /** Close the valerie structure.
913 */
914
915 void valerie_close( valerie this )
916 {
917 if ( this != NULL )
918 {
919 valerie_set_last_response( this, NULL );
920 free( this );
921 }
922 }