2 * mvcp.c -- High Level Client API for Melted
3 * Copyright (C) 2002-2009 Ushodaya Enterprises Limited
4 * Author: Charles Yates <charles.yates@pandora.be>
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.
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.
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
21 /* System header files */
27 /* Application header files */
29 #include "mvcp_tokeniser.h"
30 #include "mvcp_util.h"
32 /** Initialise the mvcp structure.
35 mvcp
mvcp_init( mvcp_parser parser
)
37 mvcp
this = malloc( sizeof( mvcp_t
) );
40 memset( this, 0, sizeof( mvcp_t
) );
41 this->parser
= parser
;
46 /** Set the response structure associated to the last command.
49 static void mvcp_set_last_response( mvcp
this, mvcp_response response
)
53 if ( this->last_response
!= NULL
)
54 mvcp_response_close( this->last_response
);
55 this->last_response
= response
;
59 /** Connect to the parser.
62 mvcp_error_code
mvcp_connect( mvcp
this )
64 mvcp_error_code error
= mvcp_server_unavailable
;
65 mvcp_response response
= mvcp_parser_connect( this->parser
);
66 if ( response
!= NULL
)
68 mvcp_set_last_response( this, response
);
69 if ( mvcp_response_get_error_code( response
) == 100 )
75 /** Interpret a non-context sensitive error code.
78 static mvcp_error_code
mvcp_get_error_code( mvcp
this, mvcp_response response
)
80 mvcp_error_code error
= mvcp_server_unavailable
;
81 switch( mvcp_response_get_error_code( response
) )
84 error
= mvcp_server_unavailable
;
87 error
= mvcp_no_response
;
95 error
= mvcp_invalid_command
;
98 error
= mvcp_server_timeout
;
101 error
= mvcp_missing_argument
;
104 error
= mvcp_unit_unavailable
;
107 error
= mvcp_invalid_file
;
111 error
= mvcp_unknown_error
;
117 /** Execute a command.
120 mvcp_error_code
mvcp_execute( mvcp
this, size_t size
, const char *format
, ... )
122 mvcp_error_code error
= mvcp_server_unavailable
;
123 char *command
= malloc( size
);
124 if ( this != NULL
&& command
!= NULL
)
127 va_start( list
, format
);
128 if ( vsnprintf( command
, size
, format
, list
) != 0 )
130 mvcp_response response
= mvcp_parser_execute( this->parser
, command
);
131 mvcp_set_last_response( this, response
);
132 error
= mvcp_get_error_code( this, response
);
136 error
= mvcp_invalid_command
;
142 error
= mvcp_malloc_failed
;
148 /** Execute a command.
151 mvcp_error_code
mvcp_receive( mvcp
this, char *doc
, size_t size
, const char *format
, ... )
153 mvcp_error_code error
= mvcp_server_unavailable
;
154 char *command
= malloc( size
);
155 if ( this != NULL
&& command
!= NULL
)
158 va_start( list
, format
);
159 if ( vsnprintf( command
, size
, format
, list
) != 0 )
161 mvcp_response response
= mvcp_parser_received( this->parser
, command
, doc
);
162 mvcp_set_last_response( this, response
);
163 error
= mvcp_get_error_code( this, response
);
167 error
= mvcp_invalid_command
;
173 error
= mvcp_malloc_failed
;
179 /** Execute a command.
182 mvcp_error_code
mvcp_push( mvcp
this, mlt_service service
, size_t size
, const char *format
, ... )
184 mvcp_error_code error
= mvcp_server_unavailable
;
185 char *command
= malloc( size
);
186 if ( this != NULL
&& command
!= NULL
)
189 va_start( list
, format
);
190 if ( vsnprintf( command
, size
, format
, list
) != 0 )
192 mvcp_response response
= mvcp_parser_push( this->parser
, command
, service
);
193 mvcp_set_last_response( this, response
);
194 error
= mvcp_get_error_code( this, response
);
198 error
= mvcp_invalid_command
;
204 error
= mvcp_malloc_failed
;
210 /** Set a global property.
213 mvcp_error_code
mvcp_set( mvcp
this, char *property
, char *value
)
215 return mvcp_execute( this, 1024, "SET %s=%s", property
, value
);
218 /** Get a global property.
221 mvcp_error_code
mvcp_get( mvcp
this, char *property
, char *value
, int length
)
223 mvcp_error_code error
= mvcp_execute( this, 1024, "GET %s", property
);
224 if ( error
== mvcp_ok
)
226 mvcp_response response
= mvcp_get_last_response( this );
227 strncpy( value
, mvcp_response_get_line( response
, 1 ), length
);
235 mvcp_error_code
mvcp_run( mvcp
this, char *file
)
237 return mvcp_execute( this, 10240, "RUN \"%s\"", file
);
243 mvcp_error_code
mvcp_unit_add( mvcp
this, char *guid
, int *unit
)
245 mvcp_error_code error
= mvcp_execute( this, 1024, "UADD %s", guid
);
246 if ( error
== mvcp_ok
)
248 int length
= mvcp_response_count( this->last_response
);
249 char *line
= mvcp_response_get_line( this->last_response
, length
- 1 );
250 if ( line
== NULL
|| sscanf( line
, "U%d", unit
) != 1 )
251 error
= mvcp_unit_creation_failed
;
255 if ( error
== mvcp_unknown_error
)
256 error
= mvcp_unit_creation_failed
;
261 /** Load a file on the specified unit.
264 mvcp_error_code
mvcp_unit_load( mvcp
this, int unit
, char *file
)
266 return mvcp_execute( this, 10240, "LOAD U%d \"%s\"", unit
, file
);
269 static void mvcp_interpret_clip_offset( char *output
, mvcp_clip_offset offset
, int clip
)
274 sprintf( output
, "%d", clip
);
278 sprintf( output
, "%d", clip
);
280 sprintf( output
, "+%d", clip
);
285 /** Load a file on the specified unit with the specified in/out points.
288 mvcp_error_code
mvcp_unit_load_clipped( mvcp
this, int unit
, char *file
, int32_t in
, int32_t out
)
290 return mvcp_execute( this, 10240, "LOAD U%d \"%s\" %d %d", unit
, file
, in
, out
);
293 /** Load a file on the specified unit at the end of the current pump.
296 mvcp_error_code
mvcp_unit_load_back( mvcp
this, int unit
, char *file
)
298 return mvcp_execute( this, 10240, "LOAD U%d \"!%s\"", unit
, file
);
301 /** Load a file on the specified unit at the end of the pump with the specified in/out points.
304 mvcp_error_code
mvcp_unit_load_back_clipped( mvcp
this, int unit
, char *file
, int32_t in
, int32_t out
)
306 return mvcp_execute( this, 10240, "LOAD U%d \"!%s\" %d %d", unit
, file
, in
, out
);
309 /** Append a file on the specified unit.
312 mvcp_error_code
mvcp_unit_append( mvcp
this, int unit
, char *file
, int32_t in
, int32_t out
)
314 return mvcp_execute( this, 10240, "APND U%d \"%s\" %d %d", unit
, file
, in
, out
);
317 /** Push a service on to a unit.
320 mvcp_error_code
mvcp_unit_receive( mvcp
this, int unit
, char *command
, char *doc
)
322 return mvcp_receive( this, doc
, 10240, "PUSH U%d %s", unit
, command
);
325 /** Push a service on to a unit.
328 mvcp_error_code
mvcp_unit_push( mvcp
this, int unit
, char *command
, mlt_service service
)
330 return mvcp_push( this, service
, 10240, "PUSH U%d %s", unit
, command
);
333 /** Clean the unit - this function removes all but the currently playing clip.
336 mvcp_error_code
mvcp_unit_clean( mvcp
this, int unit
)
338 return mvcp_execute( this, 1024, "CLEAN U%d", unit
);
341 /** Clear the unit - this function removes all clips.
344 mvcp_error_code
mvcp_unit_clear( mvcp
this, int unit
)
346 return mvcp_execute( this, 1024, "CLEAR U%d", unit
);
349 /** Wipe the unit - this function removes all clips before the current one.
352 mvcp_error_code
mvcp_unit_wipe( mvcp
this, int unit
)
354 return mvcp_execute( this, 1024, "WIPE U%d", unit
);
357 /** Move clips on the units playlist.
360 mvcp_error_code
mvcp_unit_clip_move( mvcp
this, int unit
, mvcp_clip_offset src_offset
, int src
, mvcp_clip_offset dest_offset
, int dest
)
364 mvcp_interpret_clip_offset( temp1
, src_offset
, src
);
365 mvcp_interpret_clip_offset( temp2
, dest_offset
, dest
);
366 return mvcp_execute( this, 1024, "MOVE U%d %s %s", unit
, temp1
, temp2
);
369 /** Remove clip at the specified position.
372 mvcp_error_code
mvcp_unit_clip_remove( mvcp
this, int unit
, mvcp_clip_offset offset
, int clip
)
375 mvcp_interpret_clip_offset( temp
, offset
, clip
);
376 return mvcp_execute( this, 1024, "REMOVE U%d %s", unit
, temp
);
379 /** Remove the currently playing clip.
382 mvcp_error_code
mvcp_unit_remove_current_clip( mvcp
this, int unit
)
384 return mvcp_execute( this, 1024, "REMOVE U%d", unit
);
387 /** Insert clip at the specified position.
390 mvcp_error_code
mvcp_unit_clip_insert( mvcp
this, int unit
, mvcp_clip_offset offset
, int clip
, char *file
, int32_t in
, int32_t out
)
393 mvcp_interpret_clip_offset( temp
, offset
, clip
);
394 return mvcp_execute( this, 1024, "INSERT U%d \"%s\" %s %d %d", unit
, file
, temp
, in
, out
);
397 /** Play the unit at normal speed.
400 mvcp_error_code
mvcp_unit_play( mvcp
this, int unit
)
402 return mvcp_execute( this, 1024, "PLAY U%d 1000", unit
);
405 /** Play the unit at specified speed.
408 mvcp_error_code
mvcp_unit_play_at_speed( mvcp
this, int unit
, int speed
)
410 return mvcp_execute( this, 10240, "PLAY U%d %d", unit
, speed
);
413 /** Stop playback on the specified unit.
416 mvcp_error_code
mvcp_unit_stop( mvcp
this, int unit
)
418 return mvcp_execute( this, 1024, "STOP U%d", unit
);
421 /** Pause playback on the specified unit.
424 mvcp_error_code
mvcp_unit_pause( mvcp
this, int unit
)
426 return mvcp_execute( this, 1024, "PAUSE U%d", unit
);
429 /** Rewind the specified unit.
432 mvcp_error_code
mvcp_unit_rewind( mvcp
this, int unit
)
434 return mvcp_execute( this, 1024, "REW U%d", unit
);
437 /** Fast forward the specified unit.
440 mvcp_error_code
mvcp_unit_fast_forward( mvcp
this, int unit
)
442 return mvcp_execute( this, 1024, "FF U%d", unit
);
445 /** Step by the number of frames on the specified unit.
448 mvcp_error_code
mvcp_unit_step( mvcp
this, int unit
, int32_t step
)
450 return mvcp_execute( this, 1024, "STEP U%d %d", unit
, step
);
453 /** Goto the specified frame on the specified unit.
456 mvcp_error_code
mvcp_unit_goto( mvcp
this, int unit
, int32_t position
)
458 return mvcp_execute( this, 1024, "GOTO U%d %d", unit
, position
);
461 /** Goto the specified frame in the clip on the specified unit.
464 mvcp_error_code
mvcp_unit_clip_goto( mvcp
this, int unit
, mvcp_clip_offset offset
, int clip
, int32_t position
)
467 mvcp_interpret_clip_offset( temp
, offset
, clip
);
468 return mvcp_execute( this, 1024, "GOTO U%d %d %s", unit
, position
, temp
);
471 /** Set the in point of the loaded file on the specified unit.
474 mvcp_error_code
mvcp_unit_set_in( mvcp
this, int unit
, int32_t in
)
476 return mvcp_execute( this, 1024, "SIN U%d %d", unit
, in
);
479 /** Set the in point of the clip on the specified unit.
482 mvcp_error_code
mvcp_unit_clip_set_in( mvcp
this, int unit
, mvcp_clip_offset offset
, int clip
, int32_t in
)
485 mvcp_interpret_clip_offset( temp
, offset
, clip
);
486 return mvcp_execute( this, 1024, "SIN U%d %d %s", unit
, in
, temp
);
489 /** Set the out point of the loaded file on the specified unit.
492 mvcp_error_code
mvcp_unit_set_out( mvcp
this, int unit
, int32_t out
)
494 return mvcp_execute( this, 1024, "SOUT U%d %d", unit
, out
);
497 /** Set the out point of the clip on the specified unit.
500 mvcp_error_code
mvcp_unit_clip_set_out( mvcp
this, int unit
, mvcp_clip_offset offset
, int clip
, int32_t in
)
503 mvcp_interpret_clip_offset( temp
, offset
, clip
);
504 return mvcp_execute( this, 1024, "SOUT U%d %d %s", unit
, in
, temp
);
507 /** Clear the in point of the loaded file on the specified unit.
510 mvcp_error_code
mvcp_unit_clear_in( mvcp
this, int unit
)
512 return mvcp_execute( this, 1024, "SIN U%d -1", unit
);
515 /** Clear the out point of the loaded file on the specified unit.
518 mvcp_error_code
mvcp_unit_clear_out( mvcp
this, int unit
)
520 return mvcp_execute( this, 1024, "SOUT U%d -1", unit
);
523 /** Clear the in and out points on the loaded file on the specified unit.
526 mvcp_error_code
mvcp_unit_clear_in_out( mvcp
this, int unit
)
528 mvcp_error_code error
= mvcp_unit_clear_out( this, unit
);
529 if ( error
== mvcp_ok
)
530 error
= mvcp_unit_clear_in( this, unit
);
534 /** Set a unit configuration property.
537 mvcp_error_code
mvcp_unit_set( mvcp
this, int unit
, const char *name
, const char *value
)
539 return mvcp_execute( this, 1024, "USET U%d %s=%s", unit
, name
, value
);
542 /** Get a unit configuration property.
545 mvcp_error_code
mvcp_unit_get( mvcp
this, int unit
, char *name
, char *value
, int length
)
547 mvcp_error_code error
= mvcp_execute( this, 1024, "UGET U%d %s", unit
, name
);
548 if ( error
== mvcp_ok
)
550 mvcp_response response
= mvcp_get_last_response( this );
551 strncpy( value
, mvcp_response_get_line( response
, 1 ), length
);
556 /** Get a units status.
559 mvcp_error_code
mvcp_unit_status( mvcp
this, int unit
, mvcp_status status
)
561 mvcp_error_code error
= mvcp_execute( this, 1024, "USTA U%d", unit
);
562 int error_code
= mvcp_response_get_error_code( this->last_response
);
564 memset( status
, 0, sizeof( mvcp_status_t
) );
566 if ( error_code
== 202 && mvcp_response_count( this->last_response
) == 2 )
567 mvcp_status_parse( status
, mvcp_response_get_line( this->last_response
, 1 ) );
568 else if ( error_code
== 403 )
569 status
->status
= unit_undefined
;
574 /** Transfer the current settings of unit src to unit dest.
577 mvcp_error_code
mvcp_unit_transfer( mvcp
this, int src
, int dest
)
579 return mvcp_execute( this, 1024, "XFER U%d U%d", src
, dest
);
582 /** Obtain the parsers notifier.
585 mvcp_notifier
mvcp_get_notifier( mvcp
this )
588 return mvcp_parser_get_notifier( this->parser
);
593 /** List the contents of the specified directory.
596 mvcp_dir
mvcp_dir_init( mvcp
this, const char *directory
)
598 mvcp_dir dir
= malloc( sizeof( mvcp_dir_t
) );
601 memset( dir
, 0, sizeof( mvcp_dir_t
) );
602 dir
->directory
= strdup( directory
);
603 dir
->response
= mvcp_parser_executef( this->parser
, "CLS \"%s\"", directory
);
608 /** Return the error code associated to the dir.
611 mvcp_error_code
mvcp_dir_get_error_code( mvcp_dir dir
)
614 return mvcp_get_error_code( NULL
, dir
->response
);
616 return mvcp_malloc_failed
;
619 /** Get a particular file entry in the directory.
622 mvcp_error_code
mvcp_dir_get( mvcp_dir dir
, int index
, mvcp_dir_entry entry
)
624 mvcp_error_code error
= mvcp_ok
;
625 memset( entry
, 0, sizeof( mvcp_dir_entry_t
) );
626 if ( index
< mvcp_dir_count( dir
) )
628 char *line
= mvcp_response_get_line( dir
->response
, index
+ 1 );
629 mvcp_tokeniser tokeniser
= mvcp_tokeniser_init( );
630 mvcp_tokeniser_parse_new( tokeniser
, line
, " " );
632 if ( mvcp_tokeniser_count( tokeniser
) > 0 )
634 mvcp_util_strip( mvcp_tokeniser_get_string( tokeniser
, 0 ), '\"' );
635 strcpy( entry
->full
, dir
->directory
);
636 if ( entry
->full
[ strlen( entry
->full
) - 1 ] != '/' )
637 strcat( entry
->full
, "/" );
638 strcpy( entry
->name
, mvcp_tokeniser_get_string( tokeniser
, 0 ) );
639 strcat( entry
->full
, entry
->name
);
641 switch ( mvcp_tokeniser_count( tokeniser
) )
647 entry
->size
= strtoull( mvcp_tokeniser_get_string( tokeniser
, 1 ), NULL
, 10 );
650 error
= mvcp_invalid_file
;
654 mvcp_tokeniser_close( tokeniser
);
659 /** Get the number of entries in the directory
662 int mvcp_dir_count( mvcp_dir dir
)
664 if ( dir
!= NULL
&& mvcp_response_count( dir
->response
) >= 2 )
665 return mvcp_response_count( dir
->response
) - 2;
670 /** Close the directory structure.
673 void mvcp_dir_close( mvcp_dir dir
)
677 free( dir
->directory
);
678 mvcp_response_close( dir
->response
);
683 /** List the playlist of the specified unit.
686 mvcp_list
mvcp_list_init( mvcp
this, int unit
)
688 mvcp_list list
= calloc( 1, sizeof( mvcp_list_t
) );
691 list
->response
= mvcp_parser_executef( this->parser
, "LIST U%d", unit
);
692 if ( mvcp_response_count( list
->response
) >= 2 )
693 list
->generation
= atoi( mvcp_response_get_line( list
->response
, 1 ) );
698 /** Return the error code associated to the list.
701 mvcp_error_code
mvcp_list_get_error_code( mvcp_list list
)
704 return mvcp_get_error_code( NULL
, list
->response
);
706 return mvcp_malloc_failed
;
709 /** Get a particular file entry in the list.
712 mvcp_error_code
mvcp_list_get( mvcp_list list
, int index
, mvcp_list_entry entry
)
714 mvcp_error_code error
= mvcp_ok
;
715 memset( entry
, 0, sizeof( mvcp_list_entry_t
) );
716 if ( index
< mvcp_list_count( list
) )
718 char *line
= mvcp_response_get_line( list
->response
, index
+ 2 );
719 mvcp_tokeniser tokeniser
= mvcp_tokeniser_init( );
720 mvcp_tokeniser_parse_new( tokeniser
, line
, " " );
722 if ( mvcp_tokeniser_count( tokeniser
) > 0 )
724 entry
->clip
= atoi( mvcp_tokeniser_get_string( tokeniser
, 0 ) );
725 mvcp_util_strip( mvcp_tokeniser_get_string( tokeniser
, 1 ), '\"' );
726 strcpy( entry
->full
, mvcp_tokeniser_get_string( tokeniser
, 1 ) );
727 entry
->in
= atol( mvcp_tokeniser_get_string( tokeniser
, 2 ) );
728 entry
->out
= atol( mvcp_tokeniser_get_string( tokeniser
, 3 ) );
729 entry
->max
= atol( mvcp_tokeniser_get_string( tokeniser
, 4 ) );
730 entry
->size
= atol( mvcp_tokeniser_get_string( tokeniser
, 5 ) );
731 entry
->fps
= atof( mvcp_tokeniser_get_string( tokeniser
, 6 ) );
733 mvcp_tokeniser_close( tokeniser
);
738 /** Get the number of entries in the list
741 int mvcp_list_count( mvcp_list list
)
743 if ( list
!= NULL
&& mvcp_response_count( list
->response
) >= 3 )
744 return mvcp_response_count( list
->response
) - 3;
749 /** Close the list structure.
752 void mvcp_list_close( mvcp_list list
)
756 mvcp_response_close( list
->response
);
761 /** List the currently connected nodes.
764 mvcp_nodes
mvcp_nodes_init( mvcp
this )
766 mvcp_nodes nodes
= malloc( sizeof( mvcp_nodes_t
) );
769 memset( nodes
, 0, sizeof( mvcp_nodes_t
) );
770 nodes
->response
= mvcp_parser_executef( this->parser
, "NLS" );
775 /** Return the error code associated to the nodes list.
778 mvcp_error_code
mvcp_nodes_get_error_code( mvcp_nodes nodes
)
781 return mvcp_get_error_code( NULL
, nodes
->response
);
783 return mvcp_malloc_failed
;
786 /** Get a particular node entry.
789 mvcp_error_code
mvcp_nodes_get( mvcp_nodes nodes
, int index
, mvcp_node_entry entry
)
791 mvcp_error_code error
= mvcp_ok
;
792 memset( entry
, 0, sizeof( mvcp_node_entry_t
) );
793 if ( index
< mvcp_nodes_count( nodes
) )
795 char *line
= mvcp_response_get_line( nodes
->response
, index
+ 1 );
796 mvcp_tokeniser tokeniser
= mvcp_tokeniser_init( );
797 mvcp_tokeniser_parse_new( tokeniser
, line
, " " );
799 if ( mvcp_tokeniser_count( tokeniser
) == 3 )
801 entry
->node
= atoi( mvcp_tokeniser_get_string( tokeniser
, 0 ) );
802 strncpy( entry
->guid
, mvcp_tokeniser_get_string( tokeniser
, 1 ), sizeof( entry
->guid
) );
803 mvcp_util_strip( mvcp_tokeniser_get_string( tokeniser
, 2 ), '\"' );
804 strncpy( entry
->name
, mvcp_tokeniser_get_string( tokeniser
, 2 ), sizeof( entry
->name
) );
807 mvcp_tokeniser_close( tokeniser
);
812 /** Get the number of nodes
815 int mvcp_nodes_count( mvcp_nodes nodes
)
817 if ( nodes
!= NULL
&& mvcp_response_count( nodes
->response
) >= 2 )
818 return mvcp_response_count( nodes
->response
) - 2;
823 /** Close the nodes structure.
826 void mvcp_nodes_close( mvcp_nodes nodes
)
830 mvcp_response_close( nodes
->response
);
835 /** List the currently defined units.
838 mvcp_units
mvcp_units_init( mvcp
this )
840 mvcp_units units
= malloc( sizeof( mvcp_units_t
) );
843 memset( units
, 0, sizeof( mvcp_units_t
) );
844 units
->response
= mvcp_parser_executef( this->parser
, "ULS" );
849 /** Return the error code associated to the nodes list.
852 mvcp_error_code
mvcp_units_get_error_code( mvcp_units units
)
855 return mvcp_get_error_code( NULL
, units
->response
);
857 return mvcp_malloc_failed
;
860 /** Get a particular unit entry.
863 mvcp_error_code
mvcp_units_get( mvcp_units units
, int index
, mvcp_unit_entry entry
)
865 mvcp_error_code error
= mvcp_ok
;
866 memset( entry
, 0, sizeof( mvcp_unit_entry_t
) );
867 if ( index
< mvcp_units_count( units
) )
869 char *line
= mvcp_response_get_line( units
->response
, index
+ 1 );
870 mvcp_tokeniser tokeniser
= mvcp_tokeniser_init( );
871 mvcp_tokeniser_parse_new( tokeniser
, line
, " " );
873 if ( mvcp_tokeniser_count( tokeniser
) == 4 )
875 entry
->unit
= atoi( mvcp_tokeniser_get_string( tokeniser
, 0 ) + 1 );
876 entry
->node
= atoi( mvcp_tokeniser_get_string( tokeniser
, 1 ) );
877 strncpy( entry
->guid
, mvcp_tokeniser_get_string( tokeniser
, 2 ), sizeof( entry
->guid
) );
878 entry
->online
= atoi( mvcp_tokeniser_get_string( tokeniser
, 3 ) );
881 mvcp_tokeniser_close( tokeniser
);
886 /** Get the number of units
889 int mvcp_units_count( mvcp_units units
)
891 if ( units
!= NULL
&& mvcp_response_count( units
->response
) >= 2 )
892 return mvcp_response_count( units
->response
) - 2;
897 /** Close the units structure.
900 void mvcp_units_close( mvcp_units units
)
904 mvcp_response_close( units
->response
);
909 /** Get the response of the last command executed.
912 mvcp_response
mvcp_get_last_response( mvcp
this )
914 return this->last_response
;
917 /** Obtain a printable message associated to the error code provided.
920 const char *mvcp_error_description( mvcp_error_code error
)
922 const char *msg
= "Unrecognised error";
928 case mvcp_malloc_failed
:
929 msg
= "Memory allocation error";
931 case mvcp_unknown_error
:
932 msg
= "Unknown error";
934 case mvcp_no_response
:
935 msg
= "No response obtained";
937 case mvcp_invalid_command
:
938 msg
= "Invalid command";
940 case mvcp_server_timeout
:
941 msg
= "Communications with server timed out";
943 case mvcp_missing_argument
:
944 msg
= "Missing argument";
946 case mvcp_server_unavailable
:
947 msg
= "Unable to communicate with server";
949 case mvcp_unit_creation_failed
:
950 msg
= "Unit creation failed";
952 case mvcp_unit_unavailable
:
953 msg
= "Unit unavailable";
955 case mvcp_invalid_file
:
956 msg
= "Invalid file";
958 case mvcp_invalid_position
:
959 msg
= "Invalid position";
965 /** Close the mvcp structure.
968 void mvcp_close( mvcp
this )
972 mvcp_set_last_response( this, NULL
);