Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  sd.c   Sprache: C

 

/*****************************************************************************
 * sd.c: Services discovery related functions
 *****************************************************************************
 * Copyright (C) 2007-2008 the VideoLAN team
 *
 * Authors: Antoine Cellerier <dionoea at videolan tod org>
 *          Fabio Ritrovato <sephiroth87 at videolan dot org>
 *
 * 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.
 *****************************************************************************/


/*****************************************************************************
 * Preamble
 *****************************************************************************/

#ifndef  _GNU_SOURCE
#   define  _GNU_SOURCE
#endif

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <assert.h>
#include <math.h>
#include <vlc_common.h>
#include <vlc_services_discovery.h>
#include <vlc_charset.h>
#include <vlc_strings.h>
#include <vlc_hash.h>

#include "../vlc.h"
#include "../libs.h"

static int vlclua_sd_delete_common( input_item_t **pp_item )
{
    assert(pp_item != NULL);

    input_item_t *p_item = *pp_item;
    if (p_item != NULL) /* item may be NULL if already removed earlier */
        input_item_Release( p_item );

    return 1;
}

static int vlclua_sd_remove_common( lua_State *L, input_item_t **pp_item )
{
    services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L );

    if (pp_item == NULL)
        return luaL_error( L, "expected item" );

    input_item_t *p_item = *pp_item;
    if (*pp_item == NULL)
        return luaL_error( L, "already removed item" );

    services_discovery_RemoveItem( p_sd, p_item );
    input_item_Release( p_item );
    /* Make sure we won't try to remove it again */
    *pp_item = NULL;
    return 1;
}


/*** Input item ***/

static int vlclua_sd_item_delete( lua_State *L )
{
    input_item_t **pp_item = luaL_checkudata( L, 1, "input_item_t" );

    return vlclua_sd_delete_common( pp_item );
}

#define vlclua_item_luareg( a ) \
{ "set_" # a, vlclua_item_set_ ## a },

#define vlclua_item_meta( lowercase, normal ) \
static int vlclua_item_set_ ## lowercase ( lua_State *L )\
{\
    services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L );\
    input_item_t **pp_node = (input_item_t **)luaL_checkudata( L, 1, "input_item_t" );\
    if( *pp_node )\
    {\
        if( lua_isstring( L, -1 ) )\
        {\
            input_item_Set ## normal ( *pp_node, lua_tostring( L, -1 ) );\
        } else\
            msg_Err( p_sd, "Error parsing set_ " # lowercase " arguments" );\
    }\
    return 1;\
}

vlclua_item_meta(title, Title)
vlclua_item_meta(artist, Artist)
vlclua_item_meta(genre, Genre)
vlclua_item_meta(copyright, Copyright)
vlclua_item_meta(album, Album)
vlclua_item_meta(tracknum, TrackNum)
vlclua_item_meta(description, Description)
vlclua_item_meta(rating, Rating)
vlclua_item_meta(date, Date)
vlclua_item_meta(setting, Setting)
vlclua_item_meta(url, URL)
vlclua_item_meta(language, Language)
vlclua_item_meta(nowplaying, NowPlaying)
vlclua_item_meta(publisher, Publisher)
vlclua_item_meta(encodedby, EncodedBy)
vlclua_item_meta(arturl, ArtworkURL)
vlclua_item_meta(trackid, TrackID)
vlclua_item_meta(tracktotal, TrackTotal)
vlclua_item_meta(director, Director)
vlclua_item_meta(season, Season)
vlclua_item_meta(episode, Episode)
vlclua_item_meta(showname, ShowName)
vlclua_item_meta(actors, Actors)

static const luaL_Reg vlclua_item_reg[] = {
    vlclua_item_luareg(title)
    vlclua_item_luareg(artist)
    vlclua_item_luareg(genre)
    vlclua_item_luareg(copyright)
    vlclua_item_luareg(album)
    vlclua_item_luareg(tracknum)
    vlclua_item_luareg(description)
    vlclua_item_luareg(rating)
    vlclua_item_luareg(date)
    vlclua_item_luareg(setting)
    vlclua_item_luareg(url)
    vlclua_item_luareg(language)
    vlclua_item_luareg(nowplaying)
    vlclua_item_luareg(publisher)
    vlclua_item_luareg(encodedby)
    vlclua_item_luareg(arturl)
    vlclua_item_luareg(trackid)
    vlclua_item_luareg(tracktotal)
    vlclua_item_luareg(director)
    vlclua_item_luareg(season)
    vlclua_item_luareg(episode)
    vlclua_item_luareg(showname)
    vlclua_item_luareg(actors)
    { NULL, NULL }
};

static input_item_t *vlclua_sd_create_item( services_discovery_t *p_sd,
                                            lua_State *L )
{
    if( !lua_istable( L, -1 ) )
    {
        msg_Err( p_sd, "Error: argument must be table" );
        return NULL;
    }

    lua_getfield( L, -1, "path" );
    if( !lua_isstring( L, -1 ) )
    {
        msg_Err( p_sd, "Error: \"%s\" parameter is required", "path" );
        return NULL;
    }

    const char *psz_path = lua_tostring( L, -1 );

    lua_getfield( L, -2, "title" );

    const char *psz_title = luaL_checkstring( L, -1 )
       ? luaL_checkstring( L, -1 )
       : psz_path;

    input_item_t *p_input = input_item_New( psz_path, psz_title );
    lua_pop( L, 2 );

    if( unlikely(p_input == NULL) )
        return NULL;

    /* The table must be at the top of the stack when calling
     * vlclua_read_options() */

    char **ppsz_options = NULL;
    int i_options = 0;

    lua_pushvalue( L, -1 );
    vlclua_read_options( p_sd, L, &i_options, &ppsz_options );
    lua_pop( L, 1 );

    input_item_AddOptions( p_input, i_options, (const char **)ppsz_options,
                           VLC_INPUT_OPTION_TRUSTED );
    while( i_options > 0 )
        free( ppsz_options[--i_options] );
    free( ppsz_options );

    vlclua_read_meta_data( p_sd, L, p_input );
    /* This one is to be tested... */
    vlclua_read_custom_meta_data( p_sd, L, p_input );
    /* The duration is given in seconds, convert to microseconds */

    lua_getfield( L, -1, "duration" );
    if( lua_isnumber( L, -1 ) )
        p_input->i_duration = llround(lua_tonumber( L, -1 ) * 1e6);
    else if( !lua_isnil( L, -1 ) )
        msg_Warn( p_sd, "Item duration should be a number (in seconds)." );
    lua_pop( L, 1 );

    /* string to build the input item uid */
    lua_getfield( L, -1, "uiddata" );
    if( lua_isstring( L, -1 ) )
    {
        char *s = strdup( luaL_checkstring( L, -1 ) );
        if ( s )
        {
            vlc_hash_md5_t md5;
            vlc_hash_md5_Init( &md5 );
            vlc_hash_md5_Update( &md5, s, strlen( s ) );
            free( s );
            char tmp[VLC_HASH_MD5_DIGEST_HEX_SIZE];
            vlc_hash_FinishHex( &md5, tmp );
            input_item_AddInfo( p_input, "uid", "md5", "%s", tmp );
        }
    }
    lua_pop( L, 1 );

    input_item_t **udata = lua_newuserdata( L, sizeof( input_item_t * ) );
    *udata = p_input;

    if( luaL_newmetatable( L, "input_item_t" ) )
    {
        lua_newtable( L );
        luaL_register( L, NULL, vlclua_item_reg );
        lua_setfield( L, -2, "__index" );
        lua_pushcfunction( L, vlclua_sd_item_delete );
        lua_setfield( L, -2, "__gc" );
        lua_pushliteral( L, "none of your business" );
        lua_setfield( L, -2, "__metatable" );
    }
    lua_setmetatable( L, -2 );

    return p_input;
}


/*** Input item tree node ***/

static int vlclua_sd_node_delete( lua_State *L )
{
    input_item_t **pp_item = luaL_checkudata( L, 1, "node" );

    return vlclua_sd_delete_common( pp_item );
}

static int vlclua_sd_add_sub_common( services_discovery_t *p_sd,
                                     input_item_t **pp_node,
                                     input_item_t *p_input )
{
    if( *pp_node != NULL && p_input != NULL )
        services_discovery_AddSubItem( p_sd, *pp_node, p_input );
    return 1;
}

static int vlclua_node_add_subitem( lua_State *L )
{
    services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L );
    input_item_t **pp_node = (input_item_t **)luaL_checkudata( L, 1, "node" );

    return vlclua_sd_add_sub_common( p_sd, pp_node,
                                     vlclua_sd_create_item( p_sd, L ) );
}

static const luaL_Reg vlclua_node_reg[];

static input_item_t *vlclua_sd_create_node( services_discovery_t *p_sd,
                                            lua_State *L )
{
    if( !lua_istable( L, -1 ) )
    {
        msg_Err( p_sd, "Error: argument must be table" );
        return NULL;
    }

    lua_getfield( L, -1, "title" );
    if( !lua_isstring( L, -1 ) )
    {
        msg_Err( p_sd, "Error: \"%s\" parameter is required", "title" );
        return NULL;
    }

    const char *psz_name = lua_tostring( L, -1 );
    input_item_t *p_input = input_item_NewExt( INPUT_ITEM_URI_NOP, psz_name,
                                               INPUT_DURATION_INDEFINITE,
                                               ITEM_TYPE_NODE,
                                               ITEM_NET_UNKNOWN );
    lua_pop( L, 1 );

    if( unlikely(p_input == NULL) )
        return NULL;

    lua_getfield( L, -1, "arturl" );
    if( lua_isstring( L, -1 ) && strcmp( lua_tostring( L, -1 ), "" ) )
    {
        char *psz_value = strdup( lua_tostring( L, -1 ) );
        EnsureUTF8( psz_value );
        msg_Dbg( p_sd, "ArtURL: %s", psz_value );
        /* TODO: ask for art download if not local file */
        input_item_SetArtURL( p_input, psz_value );
        free( psz_value );
    }
    lua_pop( L, 1 );

    input_item_t **udata = lua_newuserdata( L, sizeof( input_item_t * ) );
    *udata = p_input;
    if( luaL_newmetatable( L, "node" ) )
    {
        lua_newtable( L );
        luaL_register( L, NULL, vlclua_node_reg );
        lua_setfield( L, -2, "__index" );
        lua_pushcfunction( L, vlclua_sd_node_delete );
        lua_setfield( L, -2, "__gc" );
    }
    lua_setmetatable( L, -2 );

    return p_input;
}

static int vlclua_node_add_subnode( lua_State *L )
{
    services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L );
    input_item_t **pp_node = (input_item_t **)luaL_checkudata( L, 1, "node" );

    return vlclua_sd_add_sub_common( p_sd, pp_node,
                                     vlclua_sd_create_node( p_sd, L ) );
}

static const luaL_Reg vlclua_node_reg[] = {
    { "add_subitem", vlclua_node_add_subitem },
    { "add_subnode", vlclua_node_add_subnode },
    { NULL, NULL }
};


/*** Services discovery instance ***/

static int vlclua_sd_add_common( services_discovery_t *p_sd,
                                 input_item_t *p_input )
{
    if( p_input != NULL )
        services_discovery_AddItem( p_sd, p_input );
    return 1;
}

static int vlclua_sd_add_item( lua_State *L )
{
    services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L );

    return vlclua_sd_add_common( p_sd, vlclua_sd_create_item( p_sd, L ) );
}

static int vlclua_sd_add_node( lua_State *L )
{
    services_discovery_t *p_sd = (services_discovery_t *)vlclua_get_this( L );

    return vlclua_sd_add_common( p_sd, vlclua_sd_create_node( p_sd, L ) );
}

static int vlclua_sd_remove_item( lua_State *L )
{
    input_item_t **pp_input = luaL_checkudata( L, 1, "input_item_t" );

    return vlclua_sd_remove_common( L, pp_input );
}

static int vlclua_sd_remove_node( lua_State *L )
{
    input_item_t **pp_input = luaL_checkudata( L, 1, "node" );

    return vlclua_sd_remove_common( L, pp_input );
}

static const luaL_Reg vlclua_sd_sd_reg[] = {
    { "add_item", vlclua_sd_add_item },
    { "add_node", vlclua_sd_add_node },
    { "remove_item", vlclua_sd_remove_item },
    { "remove_node", vlclua_sd_remove_node },
    { NULL, NULL }
};

void luaopen_sd_sd( lua_State *L )
{
    lua_newtable( L );
    luaL_register( L, NULL, vlclua_sd_sd_reg );
    lua_setfield( L, -2, "sd" );
}

Messung
CHZG
839710093

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104845
#Domains=499261