[vlc-devel] [PATCH 1/2] Add a file extension dynamic manager to libvlc.

Benjamin Gerard benjihan at users.sourceforge.net
Thu Feb 26 10:23:14 CET 2009


The file extension manager provides functions for managing known file extensions into file extension container. Each extension can be associate to given media types (audio, video, play-list and subtitles). It is possible to create/duplicate/destroy file extension container and to alter any of them by adding and removing file extensions. Additionally a general (static) file extension container can be addressed thru the FILEEXT_POOL special container.
---
 include/vlc_fileext.h |  155 ++++++++++++
 src/Makefile.am       |    2 +
 src/libvlccore.sym    |    9 +
 src/misc/fileext.c    |  650 +++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 816 insertions(+), 0 deletions(-)
 create mode 100644 include/vlc_fileext.h
 create mode 100644 src/misc/fileext.c

diff --git a/include/vlc_fileext.h b/include/vlc_fileext.h
new file mode 100644
index 0000000..304e731
--- /dev/null
+++ b/include/vlc_fileext.h
@@ -0,0 +1,155 @@
+/*****************************************************************************
+ * vlc_fileext.h: file extension for media
+ *****************************************************************************
+ * Copyright (C) 2004-2009 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Benjamin Gerard <benjihan -4t- users.sourceforge -d0t- net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef VLC_FILEEXT_H
+# define VLC_FILEEXT_H
+
+/**
+ * \file vlc_fileext.h
+ * This file defines functions and structures for handling file extensions
+ */
+
+/**
+ * \name     file extension types
+ * \{
+ * \notice   These defines are bit mask.
+ * \warning  DO NOT CHANGE ORDER without changing names table in fileext.c
+ */
+#define FILEEXT_UNKNOWN   0   /**< file extension has no type         */
+#define FILEEXT_AUDIO     1   /**< audio file extension mask.         */
+#define FILEEXT_VIDEO     2   /**< video file extension mask.         */
+#define FILEEXT_PLAYLIST  4   /**< playlist file extension mask.      */
+#define FILEEXT_SUBTITLE  8   /**< subtitle file extension mask.      */
+/** all media file extension mask (consists on audio+video+playlist). */
+#define FILEEXT_MEDIA     (FILEEXT_AUDIO|FILEEXT_VIDEO|FILEEXT_PLAYLIST)
+/** all defined file extension mask (consist on media+subtitle).      */
+#define FILEEXT_ALL_KNOWN (FILEEXT_MEDIA|FILEEXT_SUBTITLE)
+#define FILEEXT_ALL       16  /**< all (ALL_KNOWN+UNKNOW).            */
+/** invalid extension.                                                */
+#define FILEEXT_ERROR     -1
+/**
+ * \}
+ */
+
+/** Opaque type for file extension pool. */
+typedef struct fileext_pool_s * fileext_ptr_t;
+
+/** Global file extension pool. */
+#define FILEEXT_POOL ( (fileext_ptr_t) NULL )
+
+/**
+ * Get name of extension type(s).
+ *
+ * \param   types  extension type mask
+ * \retval  0      an invalid type
+ * \retval  other  a semicolon ';' separated list of extension type
+ */
+VLC_EXPORT( const char *, fileext_TypeName, ( int types ) );
+
+/**
+ * Get type of extension.
+ *
+ * \param   pool     file extension pool
+ * \param   psz_ext  single extension ("ext" or ".ext" or "*.ext")
+ * \return  FILEEXT_???
+ */
+VLC_EXPORT( int, fileext_TypeOf, ( fileext_ptr_t pool, const char * psz_ext ) );
+
+/**
+ * Get extension list of given types.
+ *
+ * \param   pool   file extension pool
+ * \param   types  extension type mask
+ * \retval  0      an invalid type
+ * \retval  ""     an empty list
+ * \retval  other  a list of extension (e.g "*.ext1;*.ext2")
+ */
+VLC_EXPORT( char *, fileext_Get, ( fileext_ptr_t pool, int types ) );
+
+/**
+ * Add a list of extension of given type.
+ *
+ * \param   pool      file extension pool
+ * \param   psz_exts  a semicolon ';' separated list of extension
+ * \param   types     extension type mask (for a single type)
+ * \retval  VLC_EGENERIC  on failure
+ * \retval  VLC_SUCCESS   on success
+ */
+VLC_EXPORT( int , fileext_Add, \
+	    ( fileext_ptr_t pool, const char * psz_exts, int types ) );
+
+/**
+ * Delete (remove) a list of extension.
+ *
+ * \param   pool      file extension pool
+ * \param   psz_exts  a semicolon ';' separated list of extension
+ * \param   types     extension type mask (for a single type)
+ * \retval  VLC_EGENERIC  on failure
+ * \retval  VLC_SUCCESS   on success
+ */
+VLC_EXPORT( int , fileext_Del, \
+	    ( fileext_ptr_t pool, const char * psz_exts, int types ) );
+
+/**
+ * Fill with default file extensions.
+ *
+ *   The fileext_Default() fill a file extension pool with an
+ *   predefined list of well known file extensions.
+ *
+ *   \note This function should not be of any use as soon as each
+ *   component registers properly its file extensions.
+ *
+ * \param   pool  file extension pool
+ * \retval  VLC_SUCCESS  on success
+ * \retval !VLC_SUCCESS  error code of failure
+ */
+VLC_EXPORT( int, fileext_Default, ( fileext_ptr_t pool ) );
+
+/**
+ * Create a new file extension pool.
+ *
+ * \param   size  initial pool size (number of extensions; 0 is allowed)
+ * \return  new file extension pool
+ * \retval  NULL  on error
+ */
+VLC_EXPORT( fileext_ptr_t, fileext_Create, ( int size ) );
+
+/**
+ * Destroy a file extension pool.
+ *
+ * \param   pool  file extension pool
+ * \return  new file extension pool
+ * \retval  NULL  on error
+ */
+VLC_EXPORT( void, fileext_Destroy, ( fileext_ptr_t pool ) );
+
+/**
+ * Duplicate a list of extension.
+ *
+ * \param   pool      file extension pool
+ * \retval  VLC_EGENERIC  on failure
+ * \retval  VLC_SUCCESS   on success
+ */
+VLC_EXPORT( fileext_ptr_t, fileext_Dup, ( fileext_ptr_t pool ) );
+
+#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 061e247..b90d4c1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -55,6 +55,7 @@ pluginsinclude_HEADERS = \
 	../include/vlc_es.h \
 	../include/vlc_es_out.h \
 	../include/vlc_events.h \
+	../include/vlc_fileext.h \
 	../include/vlc_filter.h \
 	../include/vlc_gcrypt.h \
 	../include/vlc_httpd.h \
@@ -356,6 +357,7 @@ SOURCES_libvlc_common = \
 	misc/mtime.c \
 	misc/block.c \
 	misc/es_format.c \
+	misc/fileext.c \
 	modules/modules.h \
 	modules/modules.c \
 	modules/cache.c \
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 45497fc..0efbe12 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -108,6 +108,15 @@ EnsureUTF8
 es_format_Clean
 es_format_Copy
 es_format_Init
+fileext_Add
+fileext_Create
+fileext_Default
+fileext_Del
+fileext_Destroy
+fileext_Dup
+fileext_Get
+fileext_TypeName
+fileext_TypeOf
 filename_sanitize
 filter_chain_AppendFilter
 filter_chain_AppendFromString
diff --git a/src/misc/fileext.c b/src/misc/fileext.c
new file mode 100644
index 0000000..78c5204
--- /dev/null
+++ b/src/misc/fileext.c
@@ -0,0 +1,650 @@
+/*****************************************************************************
+ * vlc_fileext.c: file extension for media
+ *****************************************************************************
+ * Copyright (C) 2004-2009 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Benjamin Gerard <benjihan -4t- users.sourceforge -d0t- net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_fileext.h>
+#include <vlc_threads.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+/** Predefined audio file extensions. */
+#define EXTENSIONS_AUDIO_STATIC				\
+   "*.a52;*.aac;*.ac3;*.dts;*.flac;*.m4a;*.m4p;*.mka;"	\
+   "*.mod;*.mp1;*.mp2;*.mp3;*.oga;*.ogg;*.oma;*.spx;"	\
+   "*.wav;*.wma;*.xm"
+
+/** Predefined video file extensions. */
+#define EXTENSIONS_VIDEO_STATIC					\
+   "*.asf;*.avi;*.divx;*.dv;*.flv;*.gxf;*.iso;*.m1v;*.m2v;"	\
+   "*.m2t;*.m2ts;*.m4v;*.mkv;*.mov;*.mp2;*.mp4;*.mpeg;*.mpeg1;"	\
+   "*.mpeg2;*.mpeg4;*.mpg;*.mts;*.mxf;*.nuv;"			\
+   "*.ogg;*.ogm;*.ogv;*.ogx;"					\
+   "*.ps;*.rm;*.rmvb;*.ts;*.vob;*.wmv;"
+
+/** Predefined playlist file extensions. */
+#define EXTENSIONS_PLAYLIST_STATIC		\
+   "*.asx;*.b4s;*.m3u;*.pls;*.vlc;*.xspf"
+
+/** Predefined media file extensions. */
+#define EXTENSIONS_MEDIA_STATIC			\
+   EXTENSIONS_VIDEO_STATIC ";"			\
+   EXTENSIONS_AUDIO_STATIC ";"			\
+   EXTENSIONS_PLAYLIST_STATIC
+
+/** Predefined subtitle file extension. */
+#define EXTENSIONS_SUBTITLE_STATIC					\
+   "*.cdg;*.idx;*.srt;*.sub;*.utf;*.ass;*.ssa;*.aqt;*.jss;*.psb;*.rt;*.smi"
+
+/** maximum bare file extension length (w/o '*.') */
+#define FILEEXT_LEN_MAX 5
+
+/** One file extension. */
+typedef struct fileext_s {
+   char psz_ext[8];		/**< bare extension name (mp3)   */
+   int  i_len;			/**< psz_ext string length       */
+   int  i_types;		/**< mixed types                 */
+} fileext_t;			/**< single file extension       */
+
+/** File extensions collection. */
+typedef struct fileext_pool_s {
+   vlc_mutex_t lock;		/**< lock to access this struct  */
+   int i_cnt;			/**< current number of extension */
+   int i_max;			/**< size of ext array           */
+   fileext_t * fileext;		/**< sorted array of extension   */
+} fileext_pool_t;
+
+/* static pool shared by all libvlc instances. */
+static fileext_pool_t mypool = {
+   VLC_STATIC_MUTEX, 0, 0, NULL
+};
+
+static const char aud_exts[] = EXTENSIONS_AUDIO_STATIC;
+static const char vid_exts[] = EXTENSIONS_VIDEO_STATIC;
+static const char pls_exts[] = EXTENSIONS_PLAYLIST_STATIC;
+static const char sub_exts[] = EXTENSIONS_SUBTITLE_STATIC;
+
+static const char * name[FILEEXT_ALL+1] =
+{
+   "unknown",			/* 00 */
+   "audio",			/* 01 */
+   "video",			/* 02 */
+   "audio;video",		/* 03 */
+   "playlist",			/* 04 */
+   "audio;playlist",		/* 05 */
+   "playlist;video",		/* 06 */
+   "media",			/* 07 */
+   "subtitle",			/* 08 */
+   "audio;subtitle",		/* 09 */
+   "video;subtitle",		/* 0A */
+   "audio;video;subtitle",	/* 0B */
+   "playlist;subtitle",		/* 0C */
+   "audio;playlist;subtitle",	/* 0D */
+   "audio;video;subtitle",	/* 0E */
+   "media;subtitle",		/* 0F */
+   "all",			/* 10 */
+};
+
+static inline int valid_type( const int type )
+{
+   return ( type >= FILEEXT_UNKNOWN && type <= FILEEXT_ALL );
+}
+
+/*
+ * Check for a valid extension.
+ *
+ * \param  ext  extension to check "*.ext" or ".ext" or "ext"
+ * \retval   0  invalid
+ * \retval  >0  ext length (strlen(ext))
+ */
+static int valid_ext( const char * ext )
+{
+   int max = FILEEXT_LEN_MAX, len = 0;
+   /* basic checking: valid string starting by a dot '.' */
+   if( !ext ) return 0;
+   if( ext[len] == '*' ) ++len, ++max;
+   if( ext[len] == '.' ) ++len, ++max;
+   /* parsing: only valid character for extension are alphanum */
+   for(; ext[len]; ++len )
+      if ( len >= max || !isalnum( ext[len] )) return 0;
+   return len;
+}
+
+/* Parse one extesion into extension list.
+ * \param  p_ext  in/out string to parse
+ * \retval     0  invalid
+ * \retval    >0  ext string length
+ */
+static int parse_exts( const char ** p_exts )
+{
+   const char * exts = *p_exts;
+   int l;
+
+   if ( *exts == '*' ) ++exts;		/* ignore '*' prefix */
+   if ( *exts == '.' ) ++exts;		/* ignore '.' prefix */
+   for ( l = 0; isalnum(exts[l]); ++l ) /* measure extension length */
+      ;
+
+   /* 1 <= length <= LEN_MAX */
+   if ( l<1 || l>FILEEXT_LEN_MAX )
+      return 0;
+   /* nul or ';' terminated  */
+   if ( exts[l] && exts[l] != ';' )
+      return 0;
+
+   *p_exts = exts;
+   return l;
+}
+
+/* lock file extension pool (enter critical section) */
+static inline void pool_lock( fileext_pool_t * pool )
+{
+   vlc_mutex_lock( &pool->lock );
+}
+
+/* unlock file extension pool (leave critical section) */
+static inline void pool_unlock( fileext_pool_t * pool )
+{
+   vlc_mutex_unlock( &pool->lock );
+}
+
+/* clean the pool: delete all file extensions */
+static void pool_cleanup( fileext_pool_t * pool )
+{
+   pool_lock( pool );
+   {
+      pool->i_cnt  = 0;
+      pool->i_max  = 0;
+      free( pool->fileext );
+      pool->fileext = 0;
+   }
+   pool_unlock( pool );
+}
+
+/* destroy the pool: clean up pool, destroy mutex, destroy the pool. */
+static void pool_destroy( fileext_pool_t * pool )
+{
+   pool_cleanup( pool );
+   /* Except for fileext static pool. */
+   if( pool != &mypool )
+   {
+      vlc_mutex_destroy( &pool->lock );
+      free( pool );
+   }
+}
+
+/* MUST BE LOCK -- ensure enough room
+ *
+ * Ensure the pool has enough room to store max file extension. It the
+ * pool does not have enough room it will be reallocated. The new size
+ * of the pool is max(size*2,max).
+ *
+ * retval  VLC_SUCCESS   on success
+ * retval  VLC_ENOMEM    on failure (realloc failed)
+ */
+static int pool_ensure( fileext_pool_t * pool, int max )
+{
+   if( max > pool->i_max )
+   {
+      fileext_t * fileext;
+      int newmax = pool->i_max * 2;
+
+      if( newmax < max ) newmax = max;
+      fileext = realloc( pool->fileext, newmax * sizeof(fileext_t) );
+      if( ! fileext )
+	 return VLC_ENOMEM;
+      pool->fileext = fileext;
+      pool->i_max   = newmax;
+   }
+   return VLC_SUCCESS;
+}
+
+/* initialize pool structure. */
+static int pool_init( fileext_pool_t * pool )
+{
+   /* Do not reset the static pool */
+   if( pool != &mypool )
+   {
+      memset( pool, 0, sizeof(*pool) );
+      vlc_mutex_init( &pool->lock );
+   }
+   return VLC_SUCCESS;
+}
+
+/* create a new empty pool. */
+static fileext_pool_t * pool_create( int size )
+{
+   fileext_pool_t * pool = malloc( sizeof(*pool) );
+
+   if( pool )
+   {
+      if ( VLC_SUCCESS != pool_init( pool ) )
+      {
+	 free( pool );
+	 pool = 0;
+      }
+      else if ( VLC_SUCCESS != pool_ensure( pool, size ) )
+      {
+	 pool_destroy( pool );
+	 pool = 0;
+      }
+   }
+   return pool;
+}
+
+/* MUST BE LOCK -- get extension list associate to given types.
+ *
+ * \return  a mallocated string
+ * \retval  NULL  on error
+ */
+static char * pool_get( fileext_pool_t * pool, int types )
+{
+   int l, i;
+   const int always = ( types == FILEEXT_ALL );
+   char * exts;
+
+   /* count matching extensions */
+   for( l = i = 0; i < pool->i_cnt; ++i )
+   {
+      if( always || pool->fileext[i].i_types == types ||
+	  ( pool->fileext[i].i_types & types ) )
+      {
+	 l += pool->fileext[i].i_len + 3;
+      }
+   }
+   /* malloc string */
+   exts = malloc( l );
+
+   if( exts )
+   {
+      for( l = i = 0; i < pool->i_cnt; ++i )
+      {
+	 if( always || pool->fileext[i].i_types == types ||
+	     ( pool->fileext[i].i_types & types ) )
+	 {
+	    exts[l++] = '*';
+	    exts[l++] = '.';
+	    strcpy( exts+l, pool->fileext[i].psz_ext );
+	    l += pool->fileext[i].i_len;
+	    exts[l++] = ';';
+	 }
+      }
+      if( l > 0 ) --l;
+      exts[l] = 0;
+   }
+   return exts;
+}
+
+/* Copy buffer with lowercase transform ( 0 < l < 8) */
+static inline void lowercpy( char * d, const char * s, int l )
+{
+   do
+      *d++ = tolower( *s++ );
+   while( --l );
+}
+
+/* Compare 2 fileext_t (qsort and bsearch callback) */
+static int fileext_cmp( const void * p_va, const void * p_vb )
+{
+   const fileext_t * p_fe_a = p_va;
+   const fileext_t * p_fe_b = p_vb;
+   return strncmp( p_fe_a->psz_ext, p_fe_b->psz_ext, sizeof(p_fe_a->psz_ext) );
+}
+
+/* MUST BE LOCK -- ascending sort file extension pool.
+ */
+static void pool_sort( fileext_pool_t * pool )
+{
+   qsort( pool->fileext, pool->i_cnt, sizeof(fileext_t), fileext_cmp );
+}
+
+/* MUST BE LOCK --  search for a file extension in the pool.
+ *
+ * retval  0  not found
+ * retval !0  matching file extension
+ */
+static fileext_t * pool_search( const fileext_pool_t * pool,
+				const char * ext, const int len )
+{
+   fileext_t key;
+   lowercpy( key.psz_ext, ext, len );
+   key.psz_ext[len] = 0;
+   return
+      bsearch( &key, pool->fileext, pool->i_cnt, sizeof(key), fileext_cmp );
+}
+
+/* MUST BE LOCK -- add a single file extension.
+ *
+ * retval -1  on error
+ * return  1  new file extension
+ * return  0  update existing file extension
+ */
+static int pool_add_ext( fileext_pool_t * pool,
+			 const char * ext, int len, int types )
+{
+   fileext_t * key
+      = pool_search( pool, ext, len );
+   int creation = !key;
+   if( creation )
+   {
+      if ( pool_ensure( pool, pool->i_cnt+1 ) == VLC_SUCCESS )
+      {
+	 key = pool->fileext + pool->i_cnt++;
+	 key->i_types = types;
+	 lowercpy( key->psz_ext, ext, len );
+	 key->psz_ext[len] = 0;
+	 key->i_len = len;
+      }
+   }
+
+   if( key )
+      key->i_types |= types;
+
+   return key ? creation : -1;
+}
+
+/* MUST BE LOCK -- add file extensions.
+ *
+ * \return  number of extension added
+ * \retval  -1  on error
+ */
+static int pool_add_exts( fileext_pool_t * pool,
+			  const char * exts, int types )
+{
+   int l, cnt = 0, creation = 0;
+
+   if ( types == FILEEXT_ALL ) types = FILEEXT_ALL_KNOWN;
+   while( l = parse_exts( &exts ), l )
+   {
+      int res = pool_add_ext( pool, exts, l, types );
+      if( res == -1 )
+      {
+	 l = 0; break;
+      }
+      ++cnt;
+      creation |= ( res == 1 );
+
+      /* ignore semicolons ';' */
+      for( exts += l; *exts == ';'; ++exts )
+	 ;
+      /* no more ? */
+      if( !*exts ) break;
+   }
+   if( creation ) pool_sort(pool);
+   return l ? cnt : -1;
+}
+
+/* MUST BE LOCKED -- remove file extensions.
+ *
+ *  Currently only remove types; the extension is never deleted but
+ *  stay in the pool in the unknown category.
+ *
+ *  retval  -1  error
+ *  return  >0  number of extension affected
+ */
+static int pool_del_exts( fileext_pool_t * pool,
+			  const char * exts, int types )
+{
+   int l, cnt = 0;
+   const int mask = ( types == FILEEXT_ALL ) ? 0 : ~types;
+
+   while( l = parse_exts( &exts ), l )
+   {
+      fileext_t * ext;
+      if ( ext = pool_search( pool,exts,l ), ext )
+      {
+	 ++cnt;
+	 ext->i_types &= mask;
+      }
+
+      /* ignore semicolons ';' */
+      for( exts += l; *exts == ';'; ++exts )
+	 ;
+      /* no more ? */
+      if( !*exts ) break;
+   }
+   return l ? cnt : -1;
+}
+
+/* MUST BE LOCKED -- duplicate a pool */
+static fileext_pool_t * pool_dup( fileext_pool_t * pool )
+{
+   fileext_pool_t * dup = pool_create( pool->i_cnt );
+
+   if( dup )
+   {
+      dup->i_cnt = pool->i_cnt;
+      memmove( dup->fileext, pool->fileext, dup->i_cnt * sizeof(fileext_t) );
+   }
+   return dup;
+}
+
+/*
+ * Get name of extension type(s).
+ *
+ * \param   types  extension type mask
+ * \retval  0      an invalid type
+ * \retval  other  a semicolon ';' separated list of extension type
+ */
+const char * fileext_TypeName( int types )
+{
+   /*    return types >= FILEEXT_UNKNOWN || type <= FILEEXT_ALL */
+   return valid_type( types )
+      ? name[types]
+      : "invalid"
+      ;
+}
+
+/*
+ * Get name of extension type(s).
+ *
+ * \param   types  extension type mask
+ * \retval  0      an invalid type
+ * \retval  other  a semicolon ';' separated list of extension type
+ */
+int fileext_TypeOf( fileext_ptr_t pool,  const char * ext )
+{
+   fileext_t * fileext;
+   int type = FILEEXT_ERROR;
+   int len  = valid_ext( ext );
+
+   if( !len )
+      return type;
+
+   pool = ( pool == FILEEXT_POOL ) ? &mypool : pool;
+   pool_lock( pool );
+   {
+      fileext = pool_search( pool, ext, len );
+      type = fileext
+	 ? fileext->i_types
+	 : FILEEXT_UNKNOWN
+	 ;
+   }
+   pool_unlock( pool );
+
+   return type;
+}
+
+/*
+ * Get extension list of given types.
+ *
+ * \param   types  extension type mask
+ * \retval  0      an invalid type
+ * \retval  ""     an empty list
+ * \retval  other  a list of extension (e.g "*.ext1;*.ext2")
+ */
+char * fileext_Get( fileext_pool_t * pool,  int types )
+{
+   char * psz_exts = NULL;
+
+   if ( valid_type( types ) )
+   {
+      pool = ( pool == FILEEXT_POOL ) ? &mypool : pool;
+      pool_lock( pool );
+      {
+	 psz_exts = pool_get( pool, types );
+      }
+      pool_unlock( pool );
+   }
+
+   return psz_exts;
+}
+
+/*
+ * Add a list of extension of given type.
+ *
+ * \param   psz_exts  a semicolon ';' separated list of extension
+ * \param   types     extension type mask (for a single type)
+ * \retval  VLC_EGENERIC  on failure
+ * \retval  VLC_SUCCESS   on success
+ */
+int fileext_Add( fileext_pool_t * pool,  const char * psz_extlist, int types )
+{
+   int res;
+
+   pool = ( pool == FILEEXT_POOL ) ? &mypool : pool;
+   pool_lock( pool );
+   {
+      res = pool_add_exts( pool, psz_extlist, types ) >= 0
+	 ? VLC_SUCCESS
+	 : VLC_EGENERIC
+	 ;
+   }
+   pool_unlock( pool );
+
+   return res;
+}
+
+/*
+ * Delete (remove) a list of extension.
+ *
+ * \param   psz_exts  a semicolon ';' separated list of extension
+ * \param   types     extension type mask (for a single type)
+ * \retval  VLC_EGENERIC  on failure
+ * \retval  VLC_SUCCESS   on success
+ */
+int fileext_Del( fileext_pool_t * pool,
+		 const char * psz_extlist, int types )
+{
+   int res;
+
+   pool = ( pool == FILEEXT_POOL ) ? &mypool : pool;
+   pool_lock( pool );
+   {
+      res = pool_del_exts( pool, psz_extlist, types ) >= 0
+	 ? VLC_SUCCESS
+	 : VLC_EGENERIC
+	 ;
+   }
+   pool_unlock( pool );
+
+   return res;
+}
+
+/*
+ * Duplicate a list of extension.
+ *
+ * \param   pool      file extension pool
+ * \param   psz_exts  a semicolon ';' separated list of extension
+ * \param   types     extension type mask (for a single type)
+ * \retval  VLC_EGENERIC  on failure
+ * \retval  VLC_SUCCESS   on success
+ */
+fileext_pool_t * fileext_Dup( fileext_pool_t * pool )
+{
+   fileext_pool_t * dup;
+
+   pool = ( pool == FILEEXT_POOL ) ? &mypool : pool;
+   pool_lock( pool );
+   {
+      dup = pool_dup( pool );
+   }
+   pool_unlock( pool );
+
+   return dup;
+}
+
+
+/*
+ * Create a new file extension pool.
+ *
+ * \param   size  initial pool size (number of extensions; 0 is allowed)
+ * \return  new file extension pool
+ * \retval  NULL  on error
+ */
+fileext_pool_t * fileext_Create( int size )
+{
+   return pool_create( size );
+}
+
+/*
+ * Destroy a file extension pool.
+ *
+ * \param   pool  file extension pool
+ * \return  new file extension pool
+ * \retval  NULL  on error
+ */
+void fileext_Destroy( fileext_pool_t * pool )
+{
+   pool = ( pool == FILEEXT_POOL ) ? &mypool : pool;
+   pool_destroy( pool );
+}
+
+
+/*
+ * Fill with default file extensions.
+ *
+ *   The fileext_Default() fill a file extension pool with an
+ *   predefined list of well known file extensions.
+ *
+ *   \note This function should not be of any use as soon as each
+ *   component registers properly its file extensions.
+ *
+ * \param   pool  file extension pool
+ * \retval  VLC_SUCCESS  on success
+ * \retval !VLC_SUCCESS  error code of failure
+ */
+int fileext_Default( fileext_pool_t * pool )
+{
+   int res = VLC_EGENERIC;
+
+   pool = ( pool == FILEEXT_POOL ) ? &mypool : pool;
+   pool_lock( pool );
+   for( ;; )
+   {
+      if ( 0 > pool_add_exts( pool, aud_exts, FILEEXT_AUDIO    ) ) break;
+      if ( 0 > pool_add_exts( pool, vid_exts, FILEEXT_VIDEO    ) ) break;
+      if ( 0 > pool_add_exts( pool, pls_exts, FILEEXT_PLAYLIST ) ) break;
+      if ( 0 > pool_add_exts( pool, sub_exts, FILEEXT_SUBTITLE ) ) break;
+      res = VLC_SUCCESS;
+      break;
+   }
+   pool_unlock( pool );
+
+   return res;
+}
-- 
1.6.1.3





More information about the vlc-devel mailing list