/***************************************************************************** * Import_B4S: main import function *****************************************************************************/ int Import_B4S( vlc_object_t *p_this ) { DEMUX_BY_EXTENSION_OR_FORCED_MSG( ".b4s", "b4s-open", "using B4S playlist reader" ); p_demux->p_sys->psz_prefix = FindPrefix( p_demux ); return VLC_SUCCESS; }
/***************************************************************************** * Import_M3U: main import function *****************************************************************************/ int Import_M3U( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t *)p_this; const uint8_t *p_peek; CHECK_PEEK( p_peek, 8 ); char *(*pf_dup) (const char *); if( POKE( p_peek, "RTSPtext", 8 ) /* QuickTime */ || demux_IsPathExtension( p_demux, ".m3u8" ) || demux_IsForced( p_demux, "m3u8" ) ) pf_dup = strdup; /* UTF-8 */ else if( POKE( p_peek, "#EXTM3U", 7 ) || demux_IsPathExtension( p_demux, ".m3u" ) || demux_IsPathExtension( p_demux, ".vlc" ) || demux_IsForced( p_demux, "m3u" ) || ContainsURL( p_demux ) ) pf_dup = FromLocaleDup; /* locale character set (?) */ else return VLC_EGENERIC; STANDARD_DEMUX_INIT_MSG( "found valid M3U playlist" ); p_demux->p_sys->psz_prefix = FindPrefix( p_demux ); p_demux->p_sys->pf_dup = pf_dup; return VLC_SUCCESS; }
void CCensor::AddItem(bool include, const UString &path, bool recursive) { UStringVector pathParts; SplitPathToParts(path, pathParts); bool forFile = true; if (pathParts.Back().IsEmpty()) { forFile = false; pathParts.DeleteBack(); } const UString &front = pathParts.Front(); bool isAbs = false; if (front.IsEmpty()) isAbs = true; else if (front.Length() == 2 && front[1] == L':') isAbs = true; else { for (int i = 0; i < pathParts.Size(); i++) { const UString &part = pathParts[i]; if (part == L".." || part == L".") { isAbs = true; break; } } } int numAbsParts = 0; if (isAbs) if (pathParts.Size() > 1) numAbsParts = pathParts.Size() - 1; else numAbsParts = 1; UString prefix; for (int i = 0; i < numAbsParts; i++) { const UString &front = pathParts.Front(); if (DoesNameContainWildCard(front)) break; prefix += front; prefix += WCHAR_PATH_SEPARATOR; pathParts.Delete(0); } int index = FindPrefix(prefix); if (index < 0) index = Pairs.Add(CPair(prefix)); CItem item; item.PathParts = pathParts; item.ForDir = true; item.ForFile = forFile; item.Recursive = recursive; Pairs[index].Head.AddItem(include, item); }
void ModeParser::AddMode(ModeHandler* mh) { /* Yes, i know, this might let people declare modes like '_' or '^'. * If they do that, thats their problem, and if i ever EVER see an * official InspIRCd developer do that, i'll beat them with a paddle! */ if ((mh->GetModeChar() < 'A') || (mh->GetModeChar() > 'z')) throw ModuleException("Invalid letter for mode " + mh->name); /* A mode prefix of ',' is not acceptable, it would f**k up server to server. * A mode prefix of ':' will f**k up both server to server, and client to server. * A mode prefix of '#' will mess up /whois and /privmsg */ PrefixMode* pm = mh->IsPrefixMode(); if (pm) { if ((pm->GetPrefix() > 126) || (pm->GetPrefix() == ',') || (pm->GetPrefix() == ':') || (pm->GetPrefix() == '#')) throw ModuleException("Invalid prefix for mode " + mh->name); if (FindPrefix(pm->GetPrefix())) throw ModuleException("Prefix already exists for mode " + mh->name); } ModeHandler*& slot = modehandlers[mh->GetModeType()][mh->GetModeChar()-65]; if (slot) throw ModuleException("Letter is already in use for mode " + mh->name); // The mode needs an id if it is either a user mode, a simple mode (flag) or a parameter mode. // Otherwise (for listmodes and prefix modes) the id remains MODEID_MAX, which is invalid. ModeHandler::Id modeid = MODEID_MAX; if ((mh->GetModeType() == MODETYPE_USER) || (mh->IsParameterMode()) || (!mh->IsListMode())) modeid = AllocateModeId(mh->GetModeType()); if (!modehandlersbyname[mh->GetModeType()].insert(std::make_pair(mh->name, mh)).second) throw ModuleException("Mode name already in use: " + mh->name); // Everything is fine, add the mode // If we allocated an id for this mode then save it and put the mode handler into the slot if (modeid != MODEID_MAX) { mh->modeid = modeid; modehandlersbyid[mh->GetModeType()][modeid] = mh; } slot = mh; if (pm) mhlist.prefix.push_back(pm); else if (mh->IsListModeBase()) mhlist.list.push_back(mh->IsListModeBase()); RecreateModeListFor004Numeric(); }
/***************************************************************************** * Import_ZPL: main import function *****************************************************************************/ int Import_ZPL( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t *)p_this; if(! ( demux_IsPathExtension( p_demux, ".zpl" ) || demux_IsForced( p_demux, "zpl" ))) return VLC_EGENERIC; STANDARD_DEMUX_INIT_MSG( "found valid ZPL playlist" ); p_demux->p_sys->psz_prefix = FindPrefix( p_demux ); return VLC_SUCCESS; }
ThreadError Local::RemoveHasRoutePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) { ThreadError error = kThreadError_None; PrefixTlv *tlv; VerifyOrExit((tlv = FindPrefix(aPrefix, aPrefixLength)) != NULL, error = kThreadError_Error); VerifyOrExit(FindHasRoute(*tlv) != NULL, error = kThreadError_Error); Remove(reinterpret_cast<uint8_t *>(tlv), sizeof(NetworkDataTlv) + tlv->GetLength()); exit: otDumpDebgNetData("remove done", mTlvs, mLength); return error; }
/***************************************************************************** * Import_M3U: main import function *****************************************************************************/ int Import_M3U( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t *)p_this; const uint8_t *p_peek; char *(*pf_dup) (const char *) = GuessEncoding; int offset = 0; CHECK_FILE(); if( vlc_stream_Peek( p_demux->s, &p_peek, 3 ) == 3 && !memcmp( p_peek, "\xef\xbb\xbf", 3) ) { pf_dup = CheckUnicode; /* UTF-8 Byte Order Mark */ offset = 3; } if( demux_IsPathExtension( p_demux, ".m3u8" ) || demux_IsForced( p_demux, "m3u8" ) || CheckContentType( p_demux->s, "application/vnd.apple.mpegurl" ) ) pf_dup = CheckUnicode; /* UTF-8 file type */ else if( demux_IsPathExtension( p_demux, ".m3u" ) || demux_IsPathExtension( p_demux, ".vlc" ) || demux_IsForced( p_demux, "m3u" ) || ContainsURL( p_demux ) || CheckContentType( p_demux->s, "audio/x-mpegurl") ) ; /* Guess encoding */ else { if( vlc_stream_Peek( p_demux->s, &p_peek, 8 + offset ) < (8 + offset) ) return VLC_EGENERIC; p_peek += offset; if( !strncasecmp( (const char *)p_peek, "RTSPtext", 8 ) ) /* QuickTime */ pf_dup = CheckUnicode; /* UTF-8 */ else if( !memcmp( p_peek, "#EXTM3U", 7 ) ) ; /* Guess encoding */ else return VLC_EGENERIC; } vlc_stream_Seek( p_demux->s, offset ); STANDARD_DEMUX_INIT_MSG( "found valid M3U playlist" ); p_demux->p_sys->psz_prefix = FindPrefix( p_demux ); p_demux->p_sys->pf_dup = pf_dup; return VLC_SUCCESS; }
otError Local::RemoveHasRoutePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) { otError error = OT_ERROR_NONE; PrefixTlv *tlv; VerifyOrExit((tlv = FindPrefix(aPrefix, aPrefixLength)) != NULL, error = OT_ERROR_NOT_FOUND); VerifyOrExit(FindHasRoute(*tlv) != NULL, error = OT_ERROR_NOT_FOUND); Remove(reinterpret_cast<uint8_t *>(tlv), sizeof(NetworkDataTlv) + tlv->GetLength()); ClearResubmitDelayTimer(); exit: otDumpDebgNetData("remove done", mTlvs, mLength); return error; }
/***************************************************************************** * Import_WPL: main import function *****************************************************************************/ int Import_WPL( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t *)p_this; const uint8_t *p_peek; CHECK_PEEK( p_peek, 8 ); if(! ( demux_IsPathExtension( p_demux, ".wpl" ) || demux_IsForced( p_demux, "wpl" ))) return VLC_EGENERIC; STANDARD_DEMUX_INIT_MSG( "found valid WPL playlist" ); p_demux->p_sys->psz_prefix = FindPrefix( p_demux ); return VLC_SUCCESS; }
/***************************************************************************** * Import_PLS: main import function *****************************************************************************/ int Import_PLS( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t *)p_this; const uint8_t *p_peek; CHECK_PEEK( p_peek, 10 ); if( POKE( p_peek, "[playlist]", 10 ) || POKE( p_peek, "[Reference]", 10 ) || demux_IsPathExtension( p_demux, ".pls" ) || demux_IsForced( p_demux, "pls" ) ) { ; } else return VLC_EGENERIC; STANDARD_DEMUX_INIT_MSG( "found valid PLS playlist file"); p_demux->p_sys->psz_prefix = FindPrefix( p_demux ); return VLC_SUCCESS; }
bool ModeParser::AddMode(ModeHandler* mh) { unsigned char mask = 0; unsigned char pos = 0; /* Yes, i know, this might let people declare modes like '_' or '^'. * If they do that, thats their problem, and if i ever EVER see an * official InspIRCd developer do that, i'll beat them with a paddle! */ if ((mh->GetModeChar() < 'A') || (mh->GetModeChar() > 'z')) return false; /* A mode prefix of ',' is not acceptable, it would f**k up server to server. * A mode prefix of ':' will f**k up both server to server, and client to server. * A mode prefix of '#' will mess up /whois and /privmsg */ PrefixMode* pm = mh->IsPrefixMode(); if (pm) { if ((pm->GetPrefix() > 126) || (pm->GetPrefix() == ',') || (pm->GetPrefix() == ':') || (pm->GetPrefix() == '#')) return false; if (FindPrefix(pm->GetPrefix())) return false; } mh->GetModeType() == MODETYPE_USER ? mask = MASK_USER : mask = MASK_CHANNEL; pos = (mh->GetModeChar()-65) | mask; if (modehandlers[pos]) return false; // Everything is fine, add the mode modehandlers[pos] = mh; if (pm) mhlist.prefix.push_back(pm); else if (mh->IsListModeBase()) mhlist.list.push_back(mh->IsListModeBase()); RecreateModeListFor004Numeric(); return true; }
/***************************************************************************** * Import_M3U: main import function *****************************************************************************/ int Import_M3U( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t *)p_this; uint8_t *p_peek; char *psz_ext; if( stream_Peek( p_demux->s , &p_peek, 7 ) < 7 ) { return VLC_EGENERIC; } psz_ext = strrchr ( p_demux->psz_path, '.' ); if( !strncmp( p_peek, "#EXTM3U", 7 ) ) { ; } else if( ( psz_ext && !strcasecmp( psz_ext, ".m3u") ) || ( psz_ext && !strcasecmp( psz_ext, ".ram") ) || /* A .ram file can contain a single rtsp link */ ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "m3u") ) ) { ; } else { return VLC_EGENERIC; } msg_Dbg( p_demux, "found valid M3U playlist file"); p_demux->pf_control = Control; p_demux->pf_demux = Demux; p_demux->p_sys = malloc( sizeof(demux_sys_t) ); if( p_demux->p_sys == NULL ) { msg_Err( p_demux, "Out of memory" ); return VLC_ENOMEM; } p_demux->p_sys->psz_prefix = FindPrefix( p_demux ); return VLC_SUCCESS; }
static int Demux( demux_t* p_demux ) { const char* psz_name; int i_type; demux_sys_t* p_sys = p_demux->p_sys; input_item_t* p_input = GetCurrentItem( p_demux ); input_item_node_t* p_node = input_item_node_Create( p_input ); p_sys->psz_prefix = FindPrefix( p_demux ); do { i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_name ); if ( i_type == XML_READER_STARTELEM && !strcasecmp( psz_name, "head" ) ) read_head( p_demux, p_input ); else if ( i_type == XML_READER_STARTELEM && !strcasecmp( psz_name, "body" ) ) read_body( p_demux, p_node ); } while (i_type != XML_READER_ENDELEM || strcasecmp( psz_name, "smil" ) ); input_item_node_PostAndDelete( p_node ); input_item_Release( p_input ); return 0; }
/** * Import_RAM: main import function * @param p_this: this demux object * @return VLC_SUCCESS if everything is okay */ int Import_RAM( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t *)p_this; const uint8_t *p_peek; CHECK_FILE(); if(! demux_IsPathExtension( p_demux, ".ram" ) || demux_IsPathExtension( p_demux, ".rm" ) ) return VLC_EGENERIC; /* Many Real Media Files are misdetected */ if( vlc_stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC; if( !memcmp( p_peek, ".ra", 3 ) || !memcmp( p_peek, ".RMF", 4 ) ) { return VLC_EGENERIC; } STANDARD_DEMUX_INIT_MSG( "found valid RAM playlist" ); p_demux->p_sys->psz_prefix = FindPrefix( p_demux ); return VLC_SUCCESS; }
PrefixTlv *NetworkData::FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) { return FindPrefix(aPrefix, aPrefixLength, mTlvs, mLength); }
/** * Main demux callback function * @param p_demux: this demux object */ static int Demux( demux_t *p_demux ) { char *psz_prefix = FindPrefix( p_demux ); if( unlikely(psz_prefix == NULL) ) return VLC_DEMUXER_EOF; char *psz_line; char *psz_artist = NULL, *psz_album = NULL, *psz_genre = NULL, *psz_year = NULL; char *psz_author = NULL, *psz_title = NULL, *psz_copyright = NULL, *psz_cdnum = NULL, *psz_comments = NULL; mtime_t i_duration = -1; const char **ppsz_options = NULL; int i_options = 0, i_start = 0, i_stop = 0; bool b_cleanup = false; input_item_t *p_input; input_item_t *p_current_input = GetCurrentItem(p_demux); input_item_node_t *p_subitems = input_item_node_Create( p_current_input ); psz_line = vlc_stream_ReadLine( p_demux->s ); while( psz_line ) { char *psz_parse = psz_line; /* Skip leading tabs and spaces */ while( *psz_parse == ' ' || *psz_parse == '\t' || *psz_parse == '\n' || *psz_parse == '\r' ) psz_parse++; if( *psz_parse == '#' ) { /* Ignore comments */ } else if( *psz_parse ) { char *psz_mrl, *psz_option_next, *psz_option; char *psz_param, *psz_value; /* Get the MRL from the file. Note that this might contain parameters of form ?param1=value1¶m2=value2 in a RAM file */ psz_mrl = ProcessMRL( psz_parse, psz_prefix ); b_cleanup = true; if ( !psz_mrl ) goto error; /* We have the MRL, now we have to check for options and parse them from MRL */ psz_option = strchr( psz_mrl, '?' ); /* Look for start of options */ if( psz_option ) { /* Remove options from MRL because VLC can't get the file otherwise */ *psz_option = '\0'; psz_option++; psz_option_next = psz_option; while( 1 ) /* Process each option */ { /* Look for end of first option which maybe a & or \0 */ psz_option = psz_option_next; psz_option_next = strchr( psz_option, '&' ); if( psz_option_next ) { *psz_option_next = '\0'; psz_option_next++; } else psz_option_next = strchr( psz_option, '\0' ); /* Quit if options are over */ if( psz_option_next == psz_option ) break; /* Parse out param and value */ psz_param = psz_option; psz_value = strchr( psz_option, '=' ); if( psz_value == NULL ) break; *psz_value = '\0'; psz_value++; /* Take action based on parameter value in the below if else structure */ /* TODO: Remove any quotes surrounding values if required */ if( !strcmp( psz_param, "clipinfo" ) ) { ParseClipInfo( psz_value, &psz_artist, &psz_title, &psz_album, &psz_genre, &psz_year, &psz_cdnum, &psz_comments ); /* clipinfo has various sub parameters, which is parsed by this function */ } else if( !strcmp( psz_param, "author" ) ) { psz_author = vlc_uri_decode_duplicate(psz_value); EnsureUTF8( psz_author ); } else if( !strcmp( psz_param, "start" ) && strncmp( psz_mrl, "rtsp", 4 ) /* Our rtsp-real or our real demuxer is wrong */ ) { i_start = ParseTime( psz_value, strlen( psz_value ) ); char *temp; if( i_start ) { if( asprintf( &temp, ":start-time=%d", i_start ) != -1 ) INSERT_ELEM( ppsz_options, i_options, i_options, temp ); } } else if( !strcmp( psz_param, "end" ) ) { i_stop = ParseTime( psz_value, strlen( psz_value ) ); char *temp; if( i_stop ) { if( asprintf( &temp, ":stop-time=%d", i_stop ) != -1 ) INSERT_ELEM( ppsz_options, i_options, i_options, temp ); } } else if( !strcmp( psz_param, "title" ) ) { free( psz_title ); psz_title = vlc_uri_decode_duplicate(psz_value); EnsureUTF8( psz_title ); } else if( !strcmp( psz_param, "copyright" ) ) { psz_copyright = vlc_uri_decode_duplicate(psz_value); EnsureUTF8( psz_copyright ); } else { /* TODO: insert option anyway? Currently ignores*/ /* INSERT_ELEM( ppsz_options, i_options, i_options, psz_option ); */ } } } /* Create the input item and pump in all the options into playlist item */ p_input = input_item_NewExt( psz_mrl, psz_title, i_duration, ITEM_TYPE_UNKNOWN, ITEM_NET_UNKNOWN ); if( !p_input ) { free( psz_mrl ); goto error; } input_item_AddOptions( p_input, i_options, ppsz_options, 0 ); if( !EMPTY_STR( psz_artist ) ) input_item_SetArtist( p_input, psz_artist ); if( !EMPTY_STR( psz_author ) ) input_item_SetPublisher( p_input, psz_author ); if( !EMPTY_STR( psz_title ) ) input_item_SetTitle( p_input, psz_title ); if( !EMPTY_STR( psz_copyright ) ) input_item_SetCopyright( p_input, psz_copyright ); if( !EMPTY_STR( psz_album ) ) input_item_SetAlbum( p_input, psz_album ); if( !EMPTY_STR( psz_genre ) ) input_item_SetGenre( p_input, psz_genre ); if( !EMPTY_STR( psz_year ) ) input_item_SetDate( p_input, psz_year ); if( !EMPTY_STR( psz_cdnum ) ) input_item_SetTrackNum( p_input, psz_cdnum ); if( !EMPTY_STR( psz_comments ) ) input_item_SetDescription( p_input, psz_comments ); input_item_node_AppendItem( p_subitems, p_input ); vlc_gc_decref( p_input ); free( psz_mrl ); } error: /* Fetch another line */ free( psz_line ); psz_line = vlc_stream_ReadLine( p_demux->s ); if( !psz_line ) b_cleanup = true; if( b_cleanup ) { /* Cleanup state */ while( i_options-- ) free( (char*)ppsz_options[i_options] ); FREENULL( ppsz_options ); FREENULL( psz_artist ); FREENULL( psz_title ); FREENULL( psz_author ); FREENULL( psz_copyright ); FREENULL( psz_album ); FREENULL( psz_genre ); FREENULL( psz_year ); FREENULL( psz_cdnum ); FREENULL( psz_comments ); i_options = 0; i_duration = -1; i_start = 0; i_stop = 0; b_cleanup = false; } } input_item_node_PostAndDelete( p_subitems ); vlc_gc_decref(p_current_input); var_Destroy( p_demux, "m3u-extvlcopt" ); free(psz_prefix); return 0; /* Needed for correct operation of go back */ }
static int Demux( demux_t *p_demux ) { const char *psz_node = NULL; char *psz_txt = NULL; char *psz_base = FindPrefix( p_demux ); char *psz_title_asx = NULL; char *psz_entryref = NULL; xml_reader_t *p_xml_reader = NULL; input_item_t *p_current_input = GetCurrentItem( p_demux ); input_item_node_t *p_subitems = NULL; bool b_first_node = false; int i_type; int i_n_entry = 0; p_xml_reader = xml_ReaderCreate( p_demux, p_demux->s ); if( !p_xml_reader ) { msg_Err( p_demux, "Cannot parse ASX input file as XML"); goto error; } p_subitems = input_item_node_Create( p_current_input ); do { i_type = xml_ReaderNextNode( p_xml_reader, &psz_node ); if( i_type == XML_READER_STARTELEM ) { if( !b_first_node ) { if(!strncasecmp( psz_node, "ASX", 3 ) ) b_first_node = true; else { msg_Err( p_demux, "invalid root node" ); goto error; } } /* Metadata Node Handler */ if( !strncasecmp( psz_node, "TITLE", 5 ) ) { ReadElement( p_xml_reader, &psz_title_asx ); input_item_SetTitle( p_current_input, psz_title_asx ); } else if( !strncasecmp( psz_node, "AUTHOR", 6 ) ) { ReadElement( p_xml_reader, &psz_txt ); input_item_SetArtist( p_current_input, psz_txt ); } else if( !strncasecmp( psz_node, "COPYRIGHT", 9 ) ) { ReadElement( p_xml_reader, &psz_txt ); input_item_SetCopyright( p_current_input, psz_txt ); } else if( !strncasecmp( psz_node, "MOREINFO", 8 ) ) { const char *psz_tmp; do { psz_tmp = xml_ReaderNextAttr( p_xml_reader, &psz_node ); } while( psz_tmp && strncasecmp( psz_tmp, "HREF", 4 ) ); if( !psz_tmp ) // If HREF attribute doesn't exist ReadElement( p_xml_reader, &psz_txt ); else psz_txt = strdup( psz_node ); resolve_xml_special_chars( psz_txt ); input_item_SetURL( p_current_input, psz_txt ); } else if( !strncasecmp( psz_node, "ABSTRACT", 8 ) ) { ReadElement( p_xml_reader, &psz_txt ); input_item_SetDescription( p_current_input, psz_txt ); } else /* Base Node handler */ if( !strncasecmp( psz_node, "BASE", 4 ) ) ReadElement( p_xml_reader, &psz_base ); else /* Entry Ref Handler */ if( !strncasecmp( psz_node, "ENTRYREF", 7 ) ) { const char *psz_tmp; do { psz_tmp = xml_ReaderNextAttr( p_xml_reader, &psz_node ); } while( psz_tmp && !strncasecmp( psz_tmp, "HREF", 4 ) ); /* Create new input item */ input_item_t *p_input; psz_txt = strdup( psz_node ); resolve_xml_special_chars( psz_txt ); p_input = input_item_New( psz_txt, psz_title_asx ); input_item_CopyOptions( p_current_input, p_input ); input_item_node_AppendItem( p_subitems, p_input ); vlc_gc_decref( p_input ); } else /* Entry Handler */ if( !strncasecmp( psz_node, "ENTRY", 5 ) ) { ProcessEntry( &i_n_entry, p_xml_reader, p_subitems, p_current_input, psz_base); } /* FIXME Unsupported elements PARAM EVENT REPEAT ENDMARK STARTMARK */ } } while( i_type != XML_READER_ENDELEM || strncasecmp( psz_node, "ASX", 3 ) ); input_item_node_PostAndDelete( p_subitems ); p_subitems = NULL; error: free( psz_base ); free( psz_title_asx ); free( psz_entryref ); free( psz_txt ); if( p_xml_reader) xml_ReaderDelete( p_xml_reader ); if( p_subitems ) input_item_node_Delete( p_subitems ); vlc_gc_decref( p_current_input ); return 0; }
static int Demux( demux_t *p_demux ) { char *psz_prefix = FindPrefix( p_demux ); if( unlikely(psz_prefix == NULL) ) return VLC_DEMUXER_EOF; char *psz_name = NULL; char *psz_line; char *psz_mrl = NULL; char *psz_mrl_orig = NULL; char *psz_key; char *psz_value; int i_item = -1; input_item_t *p_input; input_item_t *p_current_input = GetCurrentItem(p_demux); input_item_node_t *p_subitems = input_item_node_Create( p_current_input ); while( ( psz_line = vlc_stream_ReadLine( p_demux->s ) ) ) { if( !strncasecmp( psz_line, "[playlist]", sizeof("[playlist]")-1 ) || !strncasecmp( psz_line, "[Reference]", sizeof("[Reference]")-1 ) ) { free( psz_line ); continue; } psz_key = psz_line; psz_value = strchr( psz_line, '=' ); if( psz_value ) { *psz_value='\0'; psz_value++; } else { free( psz_line ); continue; } if( !strcasecmp( psz_key, "version" ) ) { msg_Dbg( p_demux, "pls file version: %s", psz_value ); free( psz_line ); continue; } if( !strcasecmp( psz_key, "numberofentries" ) ) { msg_Dbg( p_demux, "pls should have %d entries", atoi(psz_value) ); free( psz_line); continue; } /* find the number part of of file1, title1 or length1 etc */ int i_new_item; if( sscanf( psz_key, "%*[^0-9]%d", &i_new_item ) != 1 ) { msg_Warn( p_demux, "couldn't find number of items" ); free( psz_line ); continue; } if( i_item == -1 ) i_item = i_new_item; else if( i_item != i_new_item ) { /* we found a new item, insert the previous */ if( psz_mrl ) { p_input = input_item_New( psz_mrl, psz_name ); input_item_CopyOptions( p_input, p_current_input ); input_item_node_AppendItem( p_subitems, p_input ); vlc_gc_decref( p_input ); free( psz_mrl_orig ); psz_mrl_orig = psz_mrl = NULL; } else { msg_Warn( p_demux, "no file= part found for item %d", i_item ); } free( psz_name ); psz_name = NULL; i_item = i_new_item; } if( !strncasecmp( psz_key, "file", sizeof("file") -1 ) || !strncasecmp( psz_key, "Ref", sizeof("Ref") -1 ) ) { free( psz_mrl_orig ); psz_mrl_orig = psz_mrl = ProcessMRL( psz_value, psz_prefix ); if( !strncasecmp( psz_key, "Ref", sizeof("Ref") -1 ) ) { if( !strncasecmp( psz_mrl, "http://", sizeof("http://") -1 ) ) memcpy( psz_mrl, "mmsh", 4 ); } } else if( !strncasecmp( psz_key, "title", sizeof("title") -1 ) ) { free( psz_name ); psz_name = strdup( psz_value ); } else if( !strncasecmp( psz_key, "length", sizeof("length") -1 ) ) /* duration in seconds */; else { msg_Warn( p_demux, "unknown key found in pls file: %s", psz_key ); } free( psz_line ); } /* Add last object */ if( psz_mrl ) { p_input = input_item_New( psz_mrl, psz_name ); input_item_CopyOptions( p_input, p_current_input ); input_item_node_AppendItem( p_subitems, p_input ); vlc_gc_decref( p_input ); free( psz_mrl_orig ); } else { msg_Warn( p_demux, "no file= part found for item %d", i_item ); } free( psz_name ); psz_name = NULL; input_item_node_PostAndDelete( p_subitems ); vlc_gc_decref(p_current_input); free( psz_prefix ); return 0; /* Needed for correct operation of go back */ }