00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef VLC_MEDIA_LIBRARY_H
00029 # define VLC_MEDIA_LIBRARY_H
00030
00031 # ifdef __cplusplus
00032 extern "C" {
00033 # endif
00034
00035 #include <vlc_common.h>
00036 #include <vlc_playlist.h>
00037
00038
00039
00040
00041
00042 #define ML_PERSON_ARTIST "Artist"
00043 #define ML_PERSON_ALBUM_ARTIST "Album Artist"
00044 #define ML_PERSON_ENCODER "Encoder"
00045 #define ML_PERSON_PUBLISHER "Publisher"
00046
00047
00048 #define ml_priv( gc, t ) ((t *)(((char *)(gc)) - offsetof(t, ml_gc_data)))
00049
00050
00051
00052
00053
00054
00055
00056 typedef enum
00057 {
00058 ML_ALBUM = 1,
00059 ML_ALBUM_ID,
00060 ML_ALBUM_COVER,
00061
00062 ML_ARTIST,
00063
00064 ML_ARTIST_ID,
00065
00066 ML_COMMENT,
00067 ML_COUNT_MEDIA,
00068 ML_COUNT_ALBUM,
00069 ML_COUNT_PEOPLE,
00070 ML_COVER,
00071 ML_DURATION,
00072 ML_DISC_NUMBER,
00073 ML_EXTRA,
00074 ML_FIRST_PLAYED,
00075 ML_FILESIZE,
00076 ML_GENRE,
00077 ML_ID,
00078 ML_IMPORT_TIME,
00079 ML_LANGUAGE,
00080 ML_LAST_PLAYED,
00081 ML_LAST_SKIPPED,
00082 ML_ORIGINAL_TITLE,
00083 ML_PEOPLE,
00084 ML_PEOPLE_ID,
00085 ML_PEOPLE_ROLE,
00086 ML_PLAYED_COUNT,
00087 ML_PREVIEW,
00088 ML_SKIPPED_COUNT,
00089 ML_SCORE,
00090 ML_TITLE,
00091 ML_TRACK_NUMBER,
00092 ML_TYPE,
00093 ML_URI,
00094 ML_VOTE,
00095 ML_YEAR,
00096 ML_DIRECTORY,
00097 ML_MEDIA,
00098 ML_MEDIA_SPARSE,
00099 ML_MEDIA_EXTRA,
00100
00101
00102 ML_LIMIT = -1,
00103 ML_SORT_DESC = -2,
00104 ML_SORT_ASC = -3,
00105 ML_DISTINCT = -4,
00106 ML_END = -42
00107 } ml_select_e;
00108
00109
00110 typedef enum
00111 {
00112 ML_UNKNOWN = 0,
00113 ML_AUDIO = 1 << 0,
00114 ML_VIDEO = 1 << 1,
00115 ML_STREAM = 1 << 2,
00116 ML_NODE = 1 << 3,
00117 ML_REMOVABLE = 1 << 4,
00118 } ml_type_e;
00119
00120
00121 typedef enum {
00122 ML_TYPE_INT,
00123 ML_TYPE_PSZ,
00124 ML_TYPE_TIME,
00125 ML_TYPE_MEDIA,
00126 } ml_result_type_e;
00127
00128
00129 typedef enum
00130 {
00131 ML_SET_DATABASE,
00132
00133
00134
00135 ML_INIT_DATABASE,
00136 ML_ADD_INPUT_ITEM,
00137 ML_ADD_PLAYLIST_ITEM,
00138 ML_ADD_MONITORED,
00139 ML_DEL_MONITORED,
00140 ML_GET_MONITORED,
00141 } ml_control_e;
00142
00143
00144 typedef enum
00145 {
00146 ML_OP_NONE = 0,
00147 ML_OP_AND,
00148 ML_OP_OR,
00149 ML_OP_NOT,
00150 ML_OP_SPECIAL
00151
00152 } ml_op_e;
00153
00154
00155 typedef enum
00156 {
00157 ML_COMP_NONE = 0,
00158 ML_COMP_LESSER,
00159 ML_COMP_LESSER_OR_EQUAL,
00160 ML_COMP_EQUAL,
00161 ML_COMP_GREATER_OR_EQUAL,
00162 ML_COMP_GREATER,
00163 ML_COMP_HAS,
00164 ML_COMP_STARTS_WITH,
00165 ML_COMP_ENDS_WITH,
00166 } ml_comp_e;
00167
00168
00169
00170
00171
00172 typedef struct media_library_t media_library_t;
00173 typedef struct media_library_sys_t media_library_sys_t;
00174
00175 typedef struct ml_media_t ml_media_t;
00176 typedef struct ml_result_t ml_result_t;
00177 typedef struct ml_element_t ml_element_t;
00178 typedef struct ml_person_t ml_person_t;
00179 typedef struct ml_ftree_t ml_ftree_t;
00180
00181
00182 typedef struct ml_gc_object_t
00183 {
00184 vlc_spinlock_t spin;
00185 bool pool;
00186 uintptr_t refs;
00187 void (*pf_destructor) (struct ml_gc_object_t *);
00188 } ml_gc_object_t;
00189
00190 #define ML_GC_MEMBERS ml_gc_object_t ml_gc_data;
00191
00192
00193 struct media_library_t
00194 {
00195 VLC_COMMON_MEMBERS
00196
00197 module_t *p_module;
00198 media_library_sys_t *p_sys;
00199
00200
00201 struct
00202 {
00203
00204 int ( * pf_Find ) ( media_library_t *p_media_library,
00205 vlc_array_t *p_result_array,
00206 va_list args );
00207
00208
00209 int ( * pf_FindAdv ) ( media_library_t *p_media_library,
00210 vlc_array_t *p_result_array,
00211 ml_select_e selected_type,
00212 const char *psz_lvalue,
00213 ml_ftree_t *tree );
00214
00215
00216 int ( * pf_Update ) ( media_library_t *p_media_library,
00217 ml_select_e selected_type,
00218 const char *psz_lvalue,
00219 ml_ftree_t *where,
00220 vlc_array_t *changes );
00221
00222
00223 int ( * pf_Delete ) ( media_library_t *p_media_library,
00224 vlc_array_t *p_array );
00225
00226
00227 int ( * pf_Control ) ( media_library_t *p_media_library,
00228 int i_query, va_list args );
00229
00230
00231 input_item_t* ( * pf_InputItemFromMedia ) (
00232 media_library_t *p_media_library, int i_media );
00233
00234
00235 ml_media_t* ( * pf_GetMedia ) (
00236 media_library_t *p_media_library, int i_media,
00237 ml_select_e select, bool reload );
00238 } functions;
00239 };
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 struct ml_media_t
00253 {
00254 ML_GC_MEMBERS
00255 vlc_mutex_t lock;
00256 bool b_sparse;
00257 ml_type_e i_type;
00258 int8_t i_vote;
00259 int16_t i_disc_number;
00260 int16_t i_track_number;
00261 int16_t i_year;
00262 int32_t i_id;
00263 int32_t i_score;
00264 int32_t i_album_id;
00265 int32_t i_played_count;
00266 int32_t i_skipped_count;
00267 int32_t i_bitrate;
00268 int32_t i_samplerate;
00269 int32_t i_bpm;
00270 char *psz_uri;
00271 char *psz_title;
00272 char *psz_orig_title;
00273 char *psz_album;
00274 char *psz_cover;
00275 char *psz_genre;
00276 char *psz_preview;
00277 char *psz_comment;
00278 char *psz_language;
00279 char *psz_extra;
00280 ml_person_t *p_people;
00281
00282
00283 int64_t i_filesize;
00284 mtime_t i_duration;
00285 mtime_t i_last_played;
00286 mtime_t i_last_skipped;
00287 mtime_t i_first_played;
00288 mtime_t i_import_time;
00289
00290 };
00291
00292
00293
00294
00295
00296
00297 struct ml_result_t
00298 {
00299 int32_t id;
00300 ml_result_type_e type;
00301 union
00302 {
00303
00304 int i;
00305 char *psz;
00306 mtime_t time;
00307
00308
00309 ml_media_t *p_media;
00310 } value;
00311 };
00312
00313
00314
00315
00316
00317
00318 struct ml_element_t
00319 {
00320 ml_select_e criteria;
00321 union
00322 {
00323 int i;
00324 char* str;
00325 } value;
00326 union
00327 {
00328 int i;
00329 char* str;
00330 } lvalue;
00331 };
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 struct ml_ftree_t
00345 {
00346 ml_op_e op;
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 ml_ftree_t *left;
00358 ml_ftree_t *right;
00359 ml_select_e criteria;
00360
00361
00362 ml_comp_e comp;
00363 union
00364 {
00365 int i;
00366 char *str;
00367 } value;
00368 union
00369 {
00370 int i;
00371 char *str;
00372 } lvalue;
00373
00374
00375 };
00376
00377
00378
00379
00380
00381 struct ml_person_t
00382 {
00383 char *psz_role;
00384 char *psz_name;
00385 int i_id;
00386 ml_person_t *p_next;
00387 };
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 VLC_API media_library_t* ml_Get( vlc_object_t* p_this );
00401 #define ml_Get( a ) ml_Get( VLC_OBJECT(a) )
00402
00403
00404
00405
00406
00407
00408
00409 VLC_API media_library_t* ml_Create( vlc_object_t *p_this, char* psz_name );
00410
00411
00412
00413
00414
00415 VLC_API void ml_Destroy( vlc_object_t* p_this );
00416
00417
00418
00419
00420
00421
00422
00423
00424 static inline int ml_ControlVa( media_library_t *p_media_library,
00425 ml_control_e i_type, va_list args )
00426 {
00427 return p_media_library->functions.pf_Control( p_media_library,
00428 i_type,
00429 args );
00430 }
00431
00432
00433
00434
00435
00436
00437 #define ml_Control( a, b, args... ) __ml_Control( a, b, ## args )
00438 static inline int __ml_Control( media_library_t *p_media_library,
00439 ml_control_e i_type, ... )
00440 {
00441 va_list args;
00442 int returned;
00443
00444 va_start( args, i_type );
00445 returned = ml_ControlVa( p_media_library, i_type, args );
00446 va_end( args );
00447
00448 return returned;
00449 }
00450
00451
00452
00453
00454
00455
00456 static inline int ml_AttributeIsString( ml_select_e meta )
00457 {
00458 switch( meta )
00459 {
00460
00461 case ML_ALBUM:
00462 case ML_ARTIST:
00463 case ML_COMMENT:
00464 case ML_COVER:
00465 case ML_EXTRA:
00466 case ML_GENRE:
00467 case ML_LANGUAGE:
00468 case ML_PREVIEW:
00469 case ML_PEOPLE:
00470 case ML_PEOPLE_ROLE:
00471 case ML_ORIGINAL_TITLE:
00472 case ML_TITLE:
00473 case ML_URI:
00474 return 1;
00475
00476
00477 case ML_ALBUM_ID:
00478 case ML_ARTIST_ID:
00479 case ML_DURATION:
00480 case ML_DISC_NUMBER:
00481 case ML_COUNT_MEDIA:
00482 case ML_COUNT_ALBUM:
00483 case ML_COUNT_PEOPLE:
00484 case ML_FILESIZE:
00485 case ML_FIRST_PLAYED:
00486 case ML_ID:
00487 case ML_IMPORT_TIME:
00488 case ML_LAST_PLAYED:
00489 case ML_LIMIT:
00490 case ML_PLAYED_COUNT:
00491 case ML_PEOPLE_ID:
00492 case ML_SCORE:
00493 case ML_SKIPPED_COUNT:
00494 case ML_TRACK_NUMBER:
00495 case ML_TYPE:
00496 case ML_VOTE:
00497 case ML_YEAR:
00498 return 0;
00499
00500
00501 default:
00502 return -1;
00503 }
00504 }
00505
00506
00507
00508
00509
00510
00511 static inline void ml_gc_incref( ml_media_t* p_media )
00512 {
00513 ml_gc_object_t* p_gc = &p_media->ml_gc_data;
00514 if( p_gc == NULL )
00515 return;
00516
00517 vlc_spin_lock (&p_gc->spin);
00518 ++p_gc->refs;
00519 vlc_spin_unlock (&p_gc->spin);
00520 }
00521
00522
00523
00524
00525
00526 static inline void ml_gc_decref( ml_media_t* p_media )
00527 {
00528
00529 unsigned refs;
00530 bool pool;
00531 ml_gc_object_t* p_gc = &p_media->ml_gc_data;
00532 if( p_gc == NULL )
00533 return;
00534
00535 vlc_spin_lock (&p_gc->spin);
00536 refs = --p_gc->refs;
00537 pool = p_gc->pool;
00538 vlc_spin_unlock (&p_gc->spin);
00539
00540 if( refs == 0 && !pool )
00541 {
00542 vlc_spin_destroy (&p_gc->spin);
00543 p_gc->pf_destructor (p_gc);
00544 }
00545 }
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 static inline void ml_FreePeople( ml_person_t *p_person )
00557 {
00558 if( p_person == NULL )
00559 return;
00560 ml_FreePeople( p_person->p_next );
00561 free( p_person->psz_name );
00562 free( p_person->psz_role );
00563 free( p_person );
00564 }
00565
00566
00567
00568
00569
00570
00571 static inline void ml_FreeMediaContent( ml_media_t *p_media )
00572 {
00573 free( p_media->psz_uri );
00574 free( p_media->psz_title );
00575 free( p_media->psz_orig_title );
00576 free( p_media->psz_cover );
00577 free( p_media->psz_comment );
00578 free( p_media->psz_extra );
00579 free( p_media->psz_genre );
00580 free( p_media->psz_album );
00581 free( p_media->psz_preview );
00582 free( p_media->psz_language );
00583 ml_FreePeople( p_media->p_people );
00584 p_media->b_sparse = true;
00585 p_media->i_id = 0;
00586 p_media->i_type = ML_UNKNOWN;
00587 p_media->i_album_id = 0;
00588 p_media->i_disc_number = 0;
00589 p_media->i_track_number = 0;
00590 p_media->i_year = 0;
00591 p_media->i_vote = 0;
00592 p_media->i_score = 0;
00593 p_media->i_filesize = 0;
00594 p_media->i_duration = 0;
00595 p_media->i_played_count = 0;
00596 p_media->i_last_played = 0;
00597 p_media->i_skipped_count = 0;
00598 p_media->i_last_skipped = 0;
00599 p_media->i_first_played = 0;
00600 p_media->i_import_time = 0;
00601 p_media->i_bitrate = 0;
00602 p_media->i_samplerate = 0;
00603 p_media->i_bpm = 0;
00604 }
00605
00606
00607
00608
00609
00610
00611 static inline void ml_FreeResult( ml_result_t *p_result )
00612 {
00613 if( p_result )
00614 {
00615 switch( p_result->type )
00616 {
00617 case ML_TYPE_PSZ:
00618 free( p_result->value.psz );
00619 break;
00620 case ML_TYPE_MEDIA:
00621 ml_gc_decref( p_result->value.p_media );
00622 break;
00623 default:
00624 break;
00625 }
00626 free( p_result );
00627 }
00628 }
00629
00630
00631
00632
00633
00634
00635 static inline void ml_FreeElement( ml_element_t *p_elt )
00636 {
00637 if( p_elt )
00638 {
00639 if( ml_AttributeIsString( p_elt->criteria ) )
00640 {
00641 free( p_elt->value.str );
00642 }
00643 if( p_elt->criteria == ML_PEOPLE )
00644 {
00645 free( p_elt->lvalue.str );
00646 }
00647 free( p_elt );
00648 }
00649 }
00650
00651
00652
00653
00654
00655
00656
00657 static inline void ml_DestroyResultArray( vlc_array_t *p_result_array )
00658 {
00659 for( int i = 0; i < vlc_array_count( p_result_array ); i++ )
00660 {
00661 ml_FreeResult( ( ml_result_t* ) vlc_array_item_at_index(
00662 p_result_array, i ) );
00663 }
00664 }
00665
00666
00667
00668
00669
00670
00671
00672
00673 #define ml_LockMedia( a ) vlc_mutex_lock( &a->lock )
00674 #define ml_UnlockMedia( a ) vlc_mutex_unlock( &a->lock )
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 VLC_API ml_media_t *media_New( media_library_t* p_ml, int id,
00685 ml_select_e select, bool reload );
00686
00687
00688
00689 static inline int ml_CopyPersons( ml_person_t** a, ml_person_t* b );
00690
00691
00692
00693
00694
00695
00696
00697
00698 static inline int ml_CopyMedia( ml_media_t *b, ml_media_t *a )
00699 {
00700 if( !a || !b ) return VLC_EGENERIC;
00701 if( a == b ) return VLC_SUCCESS;
00702 ml_LockMedia( a );
00703 ml_LockMedia( b );
00704 b->b_sparse = a->b_sparse;
00705 b->i_id = a->i_id;
00706 b->i_type = a->i_type;
00707 b->i_album_id = a->i_album_id;
00708 b->i_disc_number = a->i_disc_number;
00709 b->i_track_number = a->i_track_number;
00710 b->i_year = a->i_year;
00711 b->i_vote = a->i_vote;
00712 b->i_score = a->i_score;
00713 b->i_filesize = a->i_filesize;
00714 b->i_duration = a->i_duration;
00715 b->i_played_count = a->i_played_count;
00716 b->i_last_played = a->i_last_played;
00717 b->i_skipped_count = a->i_skipped_count;
00718 b->i_last_skipped = a->i_last_skipped;
00719 b->i_first_played = a->i_first_played;
00720 b->i_import_time = a->i_import_time;
00721 b->i_bitrate = a->i_bitrate;
00722 b->i_samplerate = a->i_samplerate;
00723 b->i_bpm = a->i_bpm;
00724 free( b->psz_uri );
00725 if( a->psz_uri )
00726 b->psz_uri = strdup( a->psz_uri );
00727 free( b->psz_title );
00728 if( a->psz_title )
00729 b->psz_title = strdup( a->psz_title );
00730 free( b->psz_orig_title );
00731 if( a->psz_orig_title )
00732 b->psz_orig_title = strdup( a->psz_orig_title );
00733 free( b->psz_album );
00734 if( a->psz_album )
00735 b->psz_album = strdup( a->psz_album );
00736 free( b->psz_cover );
00737 if( a->psz_cover )
00738 b->psz_cover = strdup( a->psz_cover );
00739 free( b->psz_genre );
00740 if( a->psz_genre )
00741 b->psz_genre = strdup( a->psz_genre );
00742 free( b->psz_comment );
00743 if( a->psz_comment )
00744 b->psz_comment = strdup( a->psz_comment );
00745 free( b->psz_extra );
00746 if( a->psz_extra )
00747 b->psz_extra = strdup( a->psz_extra );
00748 free( b->psz_preview );
00749 if( a->psz_preview )
00750 b->psz_preview = strdup( a->psz_preview );
00751 free( b->psz_language );
00752 if( a->psz_language )
00753 b->psz_language = strdup( a->psz_language );
00754 ml_FreePeople( b->p_people );
00755 if( a->p_people ) ml_CopyPersons( &( b->p_people ), a->p_people );
00756 ml_UnlockMedia( b );
00757 ml_UnlockMedia( a );
00758 return VLC_SUCCESS;
00759 }
00760
00761
00762
00763
00764 #define ml_FreeFindTree( tree ) ml_GenericFreeFindTree( tree, true )
00765 #define ml_ShallowFreeFindTree( tree ) ml_GenericFreeFindTree( tree, false )
00766
00767
00768
00769
00770
00771 static inline void ml_GenericFreeFindTree( ml_ftree_t* tree, bool freestrings )
00772 {
00773 if( tree == NULL )
00774 return;
00775 if( tree->left )
00776 {
00777 ml_GenericFreeFindTree( tree->left, freestrings );
00778 free( tree->left );
00779 }
00780 if( tree->right )
00781 {
00782 ml_GenericFreeFindTree( tree->right, freestrings );
00783 free( tree->right );
00784 }
00785 if( tree->op == ML_OP_NONE && ml_AttributeIsString( tree->criteria )
00786 && freestrings)
00787 {
00788 free( tree->value.str );
00789 if( tree->criteria == ML_PEOPLE )
00790 free( tree->lvalue.str );
00791 }
00792 }
00793
00794
00795
00796
00797
00798
00799 static inline int ml_FtreeHasOp( ml_ftree_t* tree )
00800 {
00801 if( tree == NULL )
00802 return 0;
00803 if( tree->criteria > 0 && tree->op == ML_OP_NONE )
00804 return 1;
00805 else
00806 return ml_FtreeHasOp( tree->left ) + ml_FtreeHasOp( tree->right );
00807 }
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822 VLC_API ml_ftree_t *ml_OpConnectChilds( ml_op_e op, ml_ftree_t* left,
00823 ml_ftree_t* right );
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834 VLC_API ml_ftree_t *ml_FtreeSpec( ml_ftree_t* tree,
00835 ml_select_e crit,
00836 int limit,
00837 char* sort );
00838
00839
00840
00841
00842
00843
00844 static inline ml_ftree_t* ml_FtreeFastAnd( ml_ftree_t* left,
00845 ml_ftree_t* right )
00846 {
00847 if( ml_FtreeHasOp( left ) == 0 )
00848 {
00849 return ml_OpConnectChilds( ML_OP_NONE, left, right );
00850 }
00851 else
00852 {
00853 return ml_OpConnectChilds( ML_OP_AND, left, right );
00854 }
00855 }
00856 #define ml_FtreeAnd( left, right ) ml_OpConnectChilds( ML_OP_AND, left, right )
00857 #define ml_FtreeOr( left, right ) ml_OpConnectChilds( ML_OP_OR, left, right )
00858 #define ml_FtreeNot( left ) ml_OpConnectChilds( ML_OP_NOT, left, NULL )
00859
00860 #define ml_FtreeSpecAsc( tree, str ) ml_FtreeSpec( tree, ML_SORT_ASC, 0, str )
00861 #define ml_FtreeSpecDesc( tree, str ) ml_FtreeSpec( tree, ML_SORT_DESC, 0, str )
00862 #define ml_FtreeSpecLimit( tree, limit ) ml_FtreeSpec( tree, ML_LIMIT, limit, NULL )
00863 #define ml_FtreeSpecDistinct( tree ) ml_FtreeSpec( tree, ML_DISTINCT, 0, NULL )
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876 static inline input_item_t* ml_CreateInputItem(
00877 media_library_t *p_media_library, int i_media_id )
00878 {
00879 return p_media_library->functions.pf_InputItemFromMedia( p_media_library,
00880 i_media_id );
00881 }
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891 static inline int __ml_Find( media_library_t *p_media_library,
00892 vlc_array_t *p_result_array, ... )
00893 {
00894 va_list args;
00895 int returned;
00896
00897 va_start( args, p_result_array );
00898 returned = p_media_library->functions.pf_Find( p_media_library,
00899 p_result_array, args );
00900 va_end( args );
00901
00902 return returned;
00903 }
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916 static inline int ml_FindAdv( media_library_t *p_media_library,
00917 vlc_array_t *p_result_array,
00918 ml_select_e result_type,
00919 char* psz_lvalue,
00920 ml_ftree_t *tree )
00921 {
00922 return p_media_library->functions.pf_FindAdv( p_media_library,
00923 p_result_array,
00924 result_type,
00925 psz_lvalue,
00926 tree );
00927 }
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937 static inline int __ml_GetValue( media_library_t *p_media_library,
00938 ml_result_t *p_result,
00939 va_list args )
00940 {
00941 vlc_array_t *p_result_array = vlc_array_new();
00942 int i_ret = p_media_library->functions.pf_Find( p_media_library,
00943 p_result_array,
00944 args );
00945 if( i_ret != VLC_SUCCESS )
00946 goto exit;
00947 if( vlc_array_count( p_result_array ) > 0 )
00948 memcpy( p_result,
00949 ( ml_result_t* ) vlc_array_item_at_index( p_result_array, 0 ),
00950 sizeof( ml_result_t) );
00951 else
00952 i_ret = VLC_EGENERIC;
00953
00954 exit:
00955
00956 vlc_array_destroy( p_result_array );
00957 return i_ret;
00958 }
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968 #define ml_GetInt( ml, ... ) __ml_GetInt( ml, __VA_ARGS__, ML_LIMIT, 1, ML_END )
00969 static inline int __ml_GetInt( media_library_t *p_media_library, ... )
00970 {
00971 va_list args;
00972 va_start( args, p_media_library );
00973 ml_result_t result;
00974 int i_ret = __ml_GetValue( p_media_library, &result, args );
00975 va_end( args );
00976 if( i_ret != VLC_SUCCESS )
00977 return i_ret;
00978 else
00979 return result.value.i;
00980 }
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991 #define ml_FindPsz( ml, ... ) __ml_GetPsz( ml, __VA_ARGS__, ML_LIMIT, 1, ML_END )
00992 static inline char* __ml_GetPsz( media_library_t *p_media_library, ... )
00993 {
00994 va_list args;
00995 va_start( args, p_media_library );
00996 ml_result_t result;
00997 int i_ret = __ml_GetValue( p_media_library, &result, args );
00998 va_end( args );
00999 if( i_ret != VLC_SUCCESS )
01000 return NULL;
01001 else
01002 return result.value.psz;
01003 }
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014 static inline int ml_Update( media_library_t *p_media_library,
01015 ml_select_e selected_type,
01016 const char* psz_lvalue,
01017 ml_ftree_t *where,
01018 vlc_array_t *changes )
01019 {
01020 return p_media_library->functions.pf_Update( p_media_library,
01021 selected_type, psz_lvalue,
01022 where, changes );
01023 }
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033 VLC_API int ml_UpdateSimple( media_library_t *p_media_library,
01034 ml_select_e selected_type,
01035 const char* psz_lvalue,
01036 int id, ... );
01037 #define ml_UpdateSimple( ml, sel, lval, id, ... ) \
01038 ml_UpdateSimple( ml, sel, lval, id, __VA_ARGS__, ML_END )
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049 static inline int
01050 ml_DeleteSimple( media_library_t *p_media_library, int id )
01051 {
01052 vlc_array_t* p_where = vlc_array_new();
01053 ml_element_t* p_find = (ml_element_t *) calloc( 1, sizeof( ml_element_t ) );
01054 p_find->criteria = ML_ID;
01055 p_find->value.i = id;
01056 vlc_array_append( p_where, p_find );
01057 int i_return = p_media_library->functions.pf_Delete( p_media_library,
01058 p_where );
01059 free( p_find );
01060 vlc_array_destroy( p_where );
01061 return i_return;
01062 }
01063
01064
01065
01066
01067
01068
01069
01070 static inline int
01071 ml_Delete( media_library_t *p_media_library, vlc_array_t* p_array )
01072 {
01073 return p_media_library->functions.pf_Delete( p_media_library,
01074 p_array );
01075 }
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090 static inline int ml_CreateAppendPersonAdv( ml_person_t **pp_person,
01091 const char* psz_role, const char* psz_name, int i_id )
01092 {
01093 if( i_id == 0 || !( psz_name && *psz_name && psz_role && *psz_role ) )
01094 return VLC_SUCCESS;
01095 if( !pp_person )
01096 return VLC_EGENERIC;
01097 if( *pp_person != NULL )
01098 return ml_CreateAppendPersonAdv( &((**pp_person).p_next),
01099 psz_role, psz_name, i_id);
01100 *pp_person = ( ml_person_t * ) calloc( 1, sizeof( ml_person_t ) );
01101 (*pp_person)->psz_name = (psz_name && *psz_name) ? strdup( psz_name ): NULL;
01102 (*pp_person)->psz_role = (psz_role && *psz_role) ? strdup( psz_role ): NULL;
01103 (*pp_person)->i_id = i_id;
01104 (*pp_person)->p_next = NULL;
01105 return VLC_SUCCESS;
01106 }
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117 static inline int ml_CreateAppendPerson( ml_person_t **pp_person,
01118 ml_person_t *p_personfrom )
01119 {
01120 return ml_CreateAppendPersonAdv( pp_person,
01121 p_personfrom->psz_role,
01122 p_personfrom->psz_name,
01123 p_personfrom->i_id );
01124 }
01125
01126
01127
01128
01129
01130
01131
01132
01133 static inline int ml_CopyPersons( ml_person_t** a, ml_person_t* b )
01134 {
01135 int i_ret;
01136 while( b )
01137 {
01138 i_ret = ml_CreateAppendPerson( a, b );
01139 if( i_ret != VLC_SUCCESS )
01140 return i_ret;
01141 b = b->p_next;
01142 }
01143 return VLC_SUCCESS;
01144 }
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154 VLC_API ml_person_t *ml_GetPersonsFromMedia( media_library_t* p_ml,
01155 ml_media_t* p_media,
01156 const char *psz_role );
01157
01158
01159 #define ml_GetAlbumArtistsFromMedia( a, b ) ml_GetPersonsFromMedia( a, b, ML_PERSON_ALBUM_ARTIST );
01160 #define ml_GetArtistsFromMedia( a, b ) ml_GetPersonsFromMedia( a, b, ML_PERSON_ARTIST );
01161 #define ml_GetEncodersFromMedia( a, b ) ml_GetPersonsFromMedia( a, b, ML_PERSON_ENCODER );
01162 #define ml_GetPublishersFromMedia( a, b ) ml_GetPersonsFromMedia( a, b, ML_PERSON_PUBLISHER );
01163
01164
01165
01166
01167
01168
01169
01170 VLC_API void ml_DeletePersonTypeFromMedia( ml_media_t* p_media,
01171 const char *psz_role );
01172
01173
01174
01175
01176
01177
01178
01179
01180 VLC_API void ml_PlaySmartPlaylistBasedOn( media_library_t* p_ml,
01181 ml_ftree_t* p_tree );
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192 #define ml_GetAlbumById( a, id ) ml_GetPsz( a, ML_ALBUM, ML_ID, id )
01193 #define ml_GetArtistById( a, id ) ml_GetPsz( a, ML_PEOPLE, ML_PERSON_ARTIST, ML_ID, id )
01194 #define ml_GetCoverUriById( a, id ) ml_GetPsz( a, ML_COVER, ML_ID, id )
01195 #define ml_GetEncoderById( a, id ) ml_GetPsz( a, ML_PEOPLE, ML_PERSON_ENCODER, ML_ID, id )
01196 #define ml_GetExtraById( a, id ) ml_GetPsz( a, ML_EXTRA, ML_ID, id )
01197 #define ml_GetGenreById( a, id ) ml_GetPsz( a, ML_GENRE, ML_ID, id )
01198 #define ml_GetOriginalTitleById( a, id ) ml_GetPsz( a, ML_ORIGINAL_TITLE, ML_ID, id )
01199 #define ml_GetPublisherById( a, id ) ml_GetPsz( a, ML_PEOPLE, ML_PERSON_PUBLISHER, ML_ID, id )
01200 #define ml_GetTitleById( a, id ) ml_GetPsz( a, ML_TITLE, ML_ID, id )
01201 #define ml_GetUriById( a, id ) ml_GetPsz( a, ML_URI, ML_ID, id )
01202
01203 #define ml_GetAlbumIdById( a, id ) ml_GetInt( a, ML_ALBUM_ID, ML_ID, id )
01204 #define ml_GetArtistIdById( a, id ) ml_GetInt( a, ML_PEOPLE_ID, ML_PERSON_ARTIST, ML_ID, id )
01205 #define ml_GetDurationById( a, id ) ml_GetInt( a, ML_DURATION, ML_ID, id )
01206 #define ml_GetEncoderIdById( a, id ) ml_GetInt( a, ML_PEOPLE_ID, ML_PERSON_ENCODER, ML_ID, id )
01207 #define ml_GetLastPlayedById( a, id ) ml_GetInt( a, ML_LAST_PLAYED, ML_ID, id )
01208 #define ml_GetPlayedCountById( a, id ) ml_GetInt( a, ML_PLAYED_COUNT, ML_ID, id )
01209 #define ml_GetPublisherIdById( a, id ) ml_GetInt( a, ML_PEOPLE_ID, ML_PERSON_PUBLISHER, ML_ID, id )
01210 #define ml_GetScoreById( a, id ) ml_GetInt( a, ML_SCORE, ML_ID, id )
01211 #define ml_GetTrackNumberById( a, id ) ml_GetInt( a, ML_TRACK_NUMBER, ML_ID, id )
01212 #define ml_GetTypeById( a, id ) ml_GetInt( a, ML_TYPE, ML_ID, id )
01213 #define ml_GetYearById( a, id ) ml_GetInt( a, ML_YEAR, ML_ID, id )
01214 #define ml_GetVoteById( a, id ) ml_GetInt( a, ML_VOTE, ML_ID, id )
01215
01216
01217 #define ml_GetAlbumId( a, b ) ml_GetInt( a, ML_ALBUM_ID, ML_ALBUM, b )
01218
01219
01220 #define ml_GetArtistId( a, b ) ml_GetInt( a, ML_PERSON_ID, ML_PERSON_ARTIST, ML_PERSON, ML_PERSON_ARTIST, b )
01221 #define ml_GetEncoderId( a, b ) ml_GetInt( a, ML_PERSON_ID, ML_PERSON_ENCODER, ML_PERSON, ML_PERSON_ENCODER, b )
01222 #define ml_GetPublisherId( a, b ) ml_GetInt( a, ML_PERSON_ID, ML_PERSON_PUBLISHER, ML_PERSON, ML_PERSON_PUBLISHER, b )
01223
01224
01225 #define ml_GetMediaCount( a, ... ) __ml_GetInt( a, ML_COUNT_MEDIA, __VA_ARGS__, ML_END )
01226 #define ml_GetAlbumCount( a, ... ) __ml_GetInt( a, ML_COUNT_ALBUM, __VA_ARGS__, ML_END )
01227 #define ml_GetPeopleCount( a, ... ) __ml_GetInt( a, ML_COUNT_PEOPLE, __VA_ARGS__, ML_END )
01228
01229 #define ml_Find( a, b, ... ) __ml_Find( a, b, __VA_ARGS__, ML_END )
01230
01231 #define ml_FindAlbum( a, b, ... ) __ml_Find( a, b, ML_ALBUM, __VA_ARGS__, ML_END )
01232 #define ml_FindArtist( a, b, ... ) __ml_Find( a, b, ML_PERSON, ML_PERSON_ARTIST, __VA_ARGS__, ML_END )
01233 #define ml_FindEncoder( a, b, ... ) __ml_Find( a, b, ML_PERSON, ML_PERSON_ENCODER, __VA_ARGS__, ML_END )
01234 #define ml_FindGenre( a, b, ... ) __ml_Find( a, b, ML_GENRE, __VA_ARGS__, ML_END )
01235 #define ml_FindMedia( a, b, ... ) __ml_Find( a, b, ML_MEDIA, __VA_ARGS__, ML_END )
01236 #define ml_FindOriginalTitle( a, b, ... ) __ml_Find( a, b, ML_ORIGINAL_TITLE, __VA_ARGS__, ML_END )
01237 #define ml_FindPublisher( a, b, ... ) __ml_Find( a, b, ML_PERSON, ML_PERSON_PUBLISHER, __VA_ARGS__, ML_END )
01238 #define ml_FindTitle( a, b, ... ) __ml_Find( a, b, ML_TITLE, __VA_ARGS__, ML_END )
01239 #define ml_FindType( a, b, ... ) __ml_Find( a, b, ML_TYPE, __VA_ARGS__, ML_END )
01240 #define ml_FindUri( a, b, ... ) __ml_Find( a, b, ML_URI, __VA_ARGS__, ML_END )
01241 #define ml_FindYear( a, b, ... ) __ml_Find( a, b, ML_YEAR, __VA_ARGS__, ML_END )
01242
01243 #define ml_FindAllAlbums( a, b ) ml_FindAlbum( a, b, ML_DISTINCT )
01244 #define ml_FindAllArtists( a, b ) ml_FindArtist( a, b, ML_DISTINCT )
01245 #define ml_FindAllGenres( a, b ) ml_FindGenre( a, b, ML_DISTINCT )
01246 #define ml_FindAllMedias( a, b ) ml_FindMedia( a, b, ML_DISTINCT )
01247 #define ml_FindAllOriginalTitles( a, b ) ml_FindOriginalTitle( a, b, ML_DISTINCT )
01248 #define ml_FindAllPublishers( a, b, ... ) ml_FindPublisher( a, b, ML_DISTINCT )
01249 #define ml_FindAllTitles( a, b ) ml_FindTitle( a, b, ML_DISTINCT )
01250 #define ml_FindAllTypes( a, b ) ml_FindType( a, b, ML_DISTINCT )
01251 #define ml_FindAllUris( a, b ) ml_FindUri( a, b, ML_DISTINCT )
01252 #define ml_FindAllYears( a, b ) ml_FindYear( a, b, ML_DISTINCT )
01253
01254 #define ml_FindAlbumAdv( a, b, c ) ml_FindAdv( a, b, ML_ALBUM, NULL, c )
01255 #define ml_FindArtistAdv( a, b, c ) ml_FindAdv( a, b, ML_PERSON, ML_PERSON_ARTIST, c )
01256 #define ml_FindEncoderAdv( a, b, c ) ml_FindAdv( a, b, ML_PERSON, ML_PERSON_ENCODER, c )
01257 #define ml_FindGenreAdv( a, b, c ) ml_FindAdv( a, b, ML_GENRE, NULL, c )
01258 #define ml_FindMediaAdv( a, b, c ) ml_FindAdv( a, b, ML_MEDIA, NULL, c )
01259 #define ml_FindOriginalTitleAdv( a, b, c ) ml_FindAdv( a, b, ML_ORIGINAL_TITLE,NULL, c )
01260 #define ml_FindPublisherAdv( a, b, c ) ml_FindAdv( a, b, ML_PUBLISHER, ML_PERSON_PUBLISHER, c )
01261 #define ml_FindTitleAdv( a, b, c ) ml_FindAdv( a, b, ML_TITLE, NULL, c )
01262 #define ml_FindTypeAdv( a, b, c ) ml_FindAdv( a, b, ML_TYPE, NULL, c )
01263 #define ml_FindUriAdv( a, b, c ) ml_FindAdv( a, b, ML_URI, NULL, c )
01264 #define ml_FindYearAdv( a, b, c ) ml_FindAdv( a, b, ML_YEAR, NULL, c )
01265
01266
01267
01268 #ifdef __cplusplus
01269 }
01270 #endif
01271
01272 #endif