>From 5b902d2a724291b91fe3885585f34b3c15ae7843 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Filip=20Ros=C3=A9en?= <filip@atch.se>
Date: Fri, 22 Jul 2016 12:28:29 +0200
Subject: [PATCH 7/8] modules/access: removal of legacy archive access/filter

Archive extraction is now handled by the libarchive based
modules/stream_extractor/archive.c, as such these files/modules are no
longer needed.
---
 modules/access/Makefile.am       |   8 -
 modules/access/archive/access.c  | 440 ---------------------------------------
 modules/access/archive/archive.c | 111 ----------
 modules/access/archive/archive.h |  39 ----
 modules/access/archive/stream.c  | 226 --------------------
 5 files changed, 824 deletions(-)
 delete mode 100644 modules/access/archive/access.c
 delete mode 100644 modules/access/archive/archive.c
 delete mode 100644 modules/access/archive/archive.h
 delete mode 100644 modules/access/archive/stream.c

diff --git a/modules/access/Makefile.am b/modules/access/Makefile.am
index 5dfa5362f0..616aa12f92 100644
--- a/modules/access/Makefile.am
+++ b/modules/access/Makefile.am
@@ -61,14 +61,6 @@ libzip_plugin_la_LIBADD += libunzip.la
 endif
 endif
 
-libaccess_archive_plugin_la_SOURCES = access/archive/access.c access/archive/stream.c \
-					access/archive/archive.h access/archive/archive.c
-libaccess_archive_plugin_la_CFLAGS = $(AM_CFLAGS) $(ARCHIVE_CFLAGS)
-libaccess_archive_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(accessdir)'
-libaccess_archive_plugin_la_LIBADD = $(ARCHIVE_LIBS)
-access_LTLIBRARIES += $(LTLIBaccess_archive)
-EXTRA_LTLIBRARIES += libaccess_archive_plugin.la
-
 ### Audio capture ###
 
 libaccess_alsa_plugin_la_SOURCES = access/alsa.c
diff --git a/modules/access/archive/access.c b/modules/access/archive/access.c
deleted file mode 100644
index f8666cf966..0000000000
--- a/modules/access/archive/access.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/*****************************************************************************
- * access.c: libarchive based access
- *****************************************************************************
- * Copyright (C) 2014 Videolan Team
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser 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.
- *****************************************************************************/
-
-#include "archive.h"
-
-#include <vlc_access.h>
-#include <vlc_url.h>
-#include <vlc_stream.h>
-
-#include <archive.h>
-#include <archive_entry.h>
-
-typedef struct callback_data_t
-{
-    char *psz_uri;
-    access_t *p_access;
-} callback_data_t;
-
-struct access_sys_t
-{
-    struct archive *p_archive;
-    bool b_source_canseek;
-    uint8_t buffer[ARCHIVE_READ_SIZE];
-
-    callback_data_t *p_callback_data;
-    unsigned int i_callback_data;
-
-    struct archive_entry *p_entry;
-    stream_t *p_stream;
-    bool b_seekable; /* Is our archive type seekable ? */
-};
-
-static ssize_t Read(access_t *p_access, void *p_data, size_t i_size)
-{
-    access_sys_t *p_sys = p_access->p_sys;
-
-    ssize_t i_read = 0;
-
-    i_read = archive_read_data(p_sys->p_archive, p_data, i_size);
-
-    if (i_read < 0)
-        i_read = 0;
-
-    return i_read;
-}
-
-static int Seek(access_t *p_access, uint64_t i_pos)
-{
-    access_sys_t *p_sys = p_access->p_sys;
-
-    if (!p_sys->b_seekable)
-        return VLC_EGENERIC;
-
-    int64_t i_ret = archive_seek_data(p_sys->p_archive, i_pos, SEEK_SET);
-    return ( i_ret < ARCHIVE_OK ) ? VLC_EGENERIC : VLC_SUCCESS;
-}
-
-static int FindVolumes(access_t *p_access, struct archive *p_archive, const char *psz_uri,
-                       char *** const pppsz_files, unsigned int * const pi_files)
-{
-    VLC_UNUSED(p_archive);
-    *pppsz_files = NULL;
-    *pi_files = 0;
-
-    static const struct
-    {
-        char const * const psz_match;
-        char const * const psz_format;
-        uint16_t i_min;
-        uint16_t i_max;
-    } patterns[] = {
-        { ".part1.rar",   "%.*s.part%.1d.rar", 2,   9 },
-        { ".part01.rar",  "%.*s.part%.2d.rar", 2,  99 },
-        { ".part001.rar", "%.*s.part%.3d.rar", 2, 999 },
-        { ".001",         "%.*s.%.3d",         2, 999 },
-        { ".000",         "%.*s.%.3d",         1, 999 },
-    };
-
-    const int i_uri_size = strlen(psz_uri);
-    const size_t i_patterns = ARRAY_SIZE(patterns);
-
-    for (size_t i = 0; i < i_patterns; i++)
-    {
-        const int i_match_size = strlen(patterns[i].psz_match);
-        if (i_uri_size < i_match_size)
-            continue;
-
-        if (!strcmp(&psz_uri[i_uri_size - i_match_size], patterns[i].psz_match))
-        {
-            char **ppsz_files = xmalloc(sizeof(char *) * patterns[i].i_max);
-
-            for (unsigned j = patterns[i].i_min; j < patterns[i].i_max; j++)
-            {
-                char *psz_newuri;
-
-                if (asprintf(&psz_newuri, patterns[i].psz_format,
-                             i_uri_size - i_match_size, psz_uri, j) == -1)
-                    break;
-
-                /* Probe URI */
-                int i_savedflags = p_access->obj.flags;
-                p_access->obj.flags |= OBJECT_FLAGS_NOINTERACT;
-                stream_t *p_stream = vlc_stream_NewURL(p_access, psz_newuri);
-                p_access->obj.flags = i_savedflags;
-                if (p_stream)
-                {
-                    ppsz_files[*pi_files] = psz_newuri;
-                    (*pi_files)++;
-                    vlc_stream_Delete(p_stream);
-                }
-                else
-                {
-                    free(psz_newuri);
-                    break;
-                }
-            }
-
-            if (*pi_files == 0)
-                FREENULL(ppsz_files);
-            *pppsz_files = ppsz_files;
-
-            return VLC_SUCCESS;
-        }
-    }
-
-    return VLC_SUCCESS;
-}
-
-static ssize_t ReadCallback(struct archive *p_archive, void *p_object, const void **pp_buffer)
-{
-    VLC_UNUSED(p_archive);
-    callback_data_t *p_data = (callback_data_t *) p_object;
-    access_sys_t *p_sys = p_data->p_access->p_sys;
-
-    *pp_buffer = &p_sys->buffer;
-    return vlc_stream_Read(p_sys->p_stream, &p_sys->buffer, ARCHIVE_READ_SIZE);
-}
-
-static ssize_t SkipCallback(struct archive *p_archive, void *p_object, ssize_t i_request)
-{
-    VLC_UNUSED(p_archive);
-    callback_data_t *p_data = (callback_data_t *) p_object;
-    access_sys_t *p_sys = p_data->p_access->p_sys;
-    ssize_t i_skipped = 0;
-
-    /* be smart as small seeks converts to reads */
-    if (p_sys->b_source_canseek)
-    {
-        int64_t i_pos = vlc_stream_Tell(p_sys->p_stream);
-        if (i_pos >=0)
-            vlc_stream_Seek(p_sys->p_stream, i_pos + i_request);
-        i_skipped = vlc_stream_Tell(p_sys->p_stream) - i_pos;
-    }
-    else while(i_request)
-    {
-        int i_skip = __MIN(INT32_MAX, i_request);
-        int i_read = vlc_stream_Read(p_sys->p_stream, NULL, i_skip);
-        if (i_read > 0)
-            i_skipped += i_read;
-        else
-            break;
-        i_request -= i_read;
-    }
-
-    return i_skipped;
-}
-
-static ssize_t SeekCallback(struct archive *p_archive, void *p_object, ssize_t i_offset, int i_whence)
-{
-    VLC_UNUSED(p_archive);
-    callback_data_t *p_data = (callback_data_t *) p_object;
-    access_sys_t *p_sys = p_data->p_access->p_sys;
-
-    ssize_t i_pos;
-
-    switch(i_whence)
-    {
-    case SEEK_CUR:
-        i_pos = vlc_stream_Tell(p_sys->p_stream);
-        break;
-    case SEEK_SET:
-        i_pos = 0;
-        break;
-    case SEEK_END:
-        i_pos = stream_Size(p_sys->p_stream) - 1;
-        break;
-    default:
-        return -1;
-    }
-
-    if (i_pos < 0)
-        return -1;
-
-    vlc_stream_Seek(p_sys->p_stream, i_pos + i_offset); /* We don't care about return val */
-    return vlc_stream_Tell(p_sys->p_stream);
-}
-
-static int SwitchCallback(struct archive *p_archive, void *p_object, void *p_object2)
-{
-    VLC_UNUSED(p_archive);
-    callback_data_t *p_data = (callback_data_t *) p_object;
-    callback_data_t *p_nextdata = (callback_data_t *) p_object2;
-    access_sys_t *p_sys = p_data->p_access->p_sys;
-
-    msg_Dbg(p_data->p_access, "opening next volume %s", p_nextdata->psz_uri);
-    vlc_stream_Delete(p_sys->p_stream);
-    p_sys->p_stream = vlc_stream_NewURL(p_nextdata->p_access, p_nextdata->psz_uri);
-    return p_sys->p_stream ? ARCHIVE_OK : ARCHIVE_FATAL;
-}
-
-static int OpenCallback(struct archive *p_archive, void *p_object)
-{
-    VLC_UNUSED(p_archive);
-    callback_data_t *p_data = (callback_data_t *) p_object;
-    access_sys_t *p_sys = p_data->p_access->p_sys;
-
-    p_sys->p_stream = vlc_stream_NewURL( p_data->p_access, p_data->psz_uri );
-    if(!p_sys->p_stream)
-        return ARCHIVE_FATAL;
-
-    /* Seek callback must only be set if calls are guaranteed to succeed */
-    vlc_stream_Control(p_sys->p_stream, STREAM_CAN_SEEK,
-                       &p_sys->b_source_canseek);
-    if(p_sys->b_source_canseek)
-        archive_read_set_seek_callback(p_sys->p_archive, SeekCallback);
-
-    return ARCHIVE_OK;
-}
-
-static int CloseCallback(struct archive *p_archive, void *p_object)
-{
-    VLC_UNUSED(p_archive);
-    callback_data_t *p_data = (callback_data_t *) p_object;
-    access_sys_t *p_sys = p_data->p_access->p_sys;
-
-    if (p_sys->p_stream)
-    {
-        vlc_stream_Delete(p_sys->p_stream);
-        p_sys->p_stream = NULL;
-    }
-
-    return ARCHIVE_OK;
-}
-
-static int Control(access_t *p_access, int i_query, va_list args)
-{
-    access_sys_t *p_sys = p_access->p_sys;
-
-    switch (i_query)
-    {
-
-    case STREAM_CAN_SEEK:
-        *va_arg(args, bool *)= p_sys->b_seekable;
-        break;
-
-    case STREAM_CAN_FASTSEEK:
-        if (!p_sys->b_seekable || !p_sys->p_stream)
-        {
-            *va_arg( args, bool* ) = false;
-            break;
-        }
-        else
-            return vlc_stream_vaControl( p_sys->p_stream, i_query, args );
-
-    case STREAM_SET_PAUSE_STATE:
-        break;
-
-    case STREAM_CAN_PAUSE:
-    case STREAM_CAN_CONTROL_PACE:
-        *va_arg(args, bool *) = true;
-        break;
-
-    case STREAM_GET_SIZE:
-        *va_arg(args, uint64_t *) = archive_entry_size(p_sys->p_entry);
-        break;
-
-    case STREAM_GET_PTS_DELAY:
-        *va_arg(args, int64_t *) = DEFAULT_PTS_DELAY;
-        break;
-
-    default:
-        return VLC_EGENERIC;
-    }
-    return VLC_SUCCESS;
-}
-
-int AccessOpen(vlc_object_t *p_object)
-{
-    access_t *p_access = (access_t*)p_object;
-    const char *sep = strchr(p_access->psz_location, ARCHIVE_SEP_CHAR);
-    if (sep == NULL)
-        return VLC_EGENERIC;
-
-    char *psz_base = strdup(p_access->psz_location);
-    if (unlikely(psz_base == NULL))
-        return VLC_ENOMEM;
-
-    char *psz_name = psz_base + (sep - p_access->psz_location);
-    *(psz_name++) = '\0';
-
-    if (vlc_uri_decode(psz_base) == NULL)
-    {
-        free(psz_base);
-        return VLC_EGENERIC;
-    }
-
-    access_sys_t *p_sys = p_access->p_sys = calloc(1, sizeof(access_sys_t));
-    p_sys->p_archive = archive_read_new();
-    if (!p_sys->p_archive)
-    {
-        msg_Err(p_access, "can't create libarchive instance: %s",
-                archive_error_string(p_sys->p_archive));
-        free(psz_base);
-        goto error;
-    }
-
-    EnableArchiveFormats(p_sys->p_archive);
-
-    /* Set up the switch callback for multiple volumes handling */
-    archive_read_set_switch_callback(p_sys->p_archive, SwitchCallback);
-
-    /* !Warn: sucks because libarchive can't guess format without reading 1st header
-     *        and it can't tell either if volumes are missing neither set following
-     *        volumes after the first Open().
-     *        We need to know volumes uri in advance then :/
-     */
-
-    /* Try to list existing volumes */
-    char **ppsz_files = NULL;
-    unsigned int i_files = 0;
-    FindVolumes(p_access, p_sys->p_archive, psz_base, &ppsz_files, &i_files);
-
-    p_sys->i_callback_data = 1 + i_files;
-    p_sys->p_callback_data = malloc(sizeof(callback_data_t) * p_sys->i_callback_data);
-    if (!p_sys->p_callback_data)
-    {
-        for(unsigned int i=0; i<i_files; i++)
-            free(ppsz_files[i]);
-        free(ppsz_files);
-        free(psz_base);
-        AccessClose(p_object);
-        return VLC_ENOMEM;
-    }
-
-    /* set up our callback struct for our main uri */
-    p_sys->p_callback_data[0].psz_uri = psz_base;
-    p_sys->p_callback_data[0].p_access = p_access;
-    archive_read_append_callback_data(p_sys->p_archive, &p_sys->p_callback_data[0]);
-
-    /* and register other volumes */
-    for(unsigned int i=0; i<i_files; i++)
-    {
-        p_sys->p_callback_data[1+i].psz_uri = ppsz_files[i];
-        p_sys->p_callback_data[1+i].p_access = p_access;
-        archive_read_append_callback_data(p_sys->p_archive, &p_sys->p_callback_data[1+i]);
-    }
-    free(ppsz_files);
-
-    if (archive_read_open2(p_sys->p_archive, &p_sys->p_callback_data[0],
-                           OpenCallback, ReadCallback, SkipCallback, CloseCallback) != ARCHIVE_OK)
-    {
-        msg_Err(p_access, "can't open archive: %s",
-                archive_error_string(p_sys->p_archive));
-        AccessClose(p_object);
-        return VLC_EGENERIC;
-    }
-
-    bool b_present = false;
-    while(archive_read_next_header(p_sys->p_archive, &p_sys->p_entry) == ARCHIVE_OK)
-    {
-        if (!strcmp(archive_entry_pathname(p_sys->p_entry), psz_name))
-        {
-            b_present = true;
-            break;
-        }
-        msg_Dbg(p_access, "skipping entry %s != %s", archive_entry_pathname(p_sys->p_entry), psz_name);
-    }
-
-    if (!b_present)
-    {
-        msg_Err(p_access, "entry '%s' not found in archive", psz_name);
-        /* entry not found */
-        goto error;
-    }
-
-    msg_Dbg(p_access, "reading entry %s %"PRId64, archive_entry_pathname(p_sys->p_entry),
-                                                  archive_entry_size(p_sys->p_entry));
-
-    /* try to guess if it is seekable or not (does not depend on backend) */
-    p_sys->b_seekable = (archive_seek_data(p_sys->p_archive, 0, SEEK_SET) >= 0);
-
-    p_access->pf_read    = Read;
-    p_access->pf_block   = NULL; /* libarchive's zerocopy keeps owning block :/ */
-    p_access->pf_control = Control;
-    p_access->pf_seek    = Seek;
-
-    return VLC_SUCCESS;
-
-error:
-    AccessClose(p_object);
-    return VLC_EGENERIC;
-}
-
-void AccessClose(vlc_object_t *p_object)
-{
-    access_t *p_access = (access_t*)p_object;
-    access_sys_t *p_sys = p_access->p_sys;
-
-    if (p_sys->p_archive)
-    {
-        archive_read_close(p_sys->p_archive);
-        archive_read_free(p_sys->p_archive);
-    }
-
-    if (p_sys->p_callback_data)
-    {
-        for(unsigned int i=0; i<p_sys->i_callback_data; i++)
-            free(p_sys->p_callback_data[i].psz_uri);
-        free(p_sys->p_callback_data);
-    }
-
-    free(p_sys);
-}
diff --git a/modules/access/archive/archive.c b/modules/access/archive/archive.c
deleted file mode 100644
index d2dd0a6059..0000000000
--- a/modules/access/archive/archive.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*****************************************************************************
- * archive.c: libarchive based stream filter
- *****************************************************************************
- * Copyright (C) 2014 Videolan Team
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser 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.
- *****************************************************************************/
-
-#include "archive.h"
-
-#include <vlc_plugin.h>
-#include <vlc_stream.h>
-
-#include <archive.h>
-
-/****************************************************************************
- * Module descriptor
- *****************************************************************************/
-vlc_module_begin()
-    set_shortname( "libarchive" )
-    set_category( CAT_INPUT )
-    set_subcategory( SUBCAT_INPUT_ACCESS )
-    set_description( N_( "libarchive access" ) )
-    set_capability( "access", 0 )
-    add_shortcut( "archive" )
-    set_callbacks( AccessOpen, AccessClose )
-    add_submodule()
-        set_shortname( "libarchive" )
-        set_subcategory( SUBCAT_INPUT_STREAM_FILTER )
-        set_description( N_( "libarchive stream filter" ) )
-        set_capability( "stream_filter", 14 ) /* less than rar and gzip */
-        set_callbacks( StreamOpen, StreamClose )
-vlc_module_end()
-
-bool ProbeArchiveFormat(stream_t *p_stream)
-{
-    struct
-    {
-        const uint16_t i_offset;
-        const uint8_t  i_length;
-        const char * const p_bytes;
-    } const magicbytes[9] = {
-        /* keep heaviest at top */
-        { 257, 5, "ustar" },        //TAR
-        { 0,   7, "Rar!\x1A\x07" }, //RAR
-        { 0,   4, "xar!" },         //XAR
-        { 2,   3, "-lh" },          //LHA/LHZ
-        { 0,   3, "PAX" },          //PAX
-        { 0,   6, "070707" },       //CPIO
-        { 0,   6, "070701" },       //CPIO
-        { 0,   6, "070702" },       //CPIO
-        { 0,   4, "MSCH" },         //CAB
-    };
-
-    const uint8_t *p_peek;
-    int i_peek = vlc_stream_Peek(p_stream, &p_peek, magicbytes[0].i_offset + magicbytes[0].i_length);
-
-    for(int i=0; i<9;i++)
-    {
-        if (i_peek <= magicbytes[i].i_offset + magicbytes[i].i_length)
-            continue;
-        else if ( !memcmp(p_peek + magicbytes[i].i_offset,
-                          magicbytes[i].p_bytes,
-                          magicbytes[i].i_length) )
-            return true;
-    }
-
-    return false;
-}
-
-void EnableArchiveFormats(struct archive *p_archive)
-{
-    //    archive_read_support_filter_bzip2(p_archive);
-    //    archive_read_support_filter_compress(p_archive);
-    //    archive_read_support_filter_gzip(p_archive);
-    //    archive_read_support_filter_grzip(p_archive);
-    //    archive_read_support_filter_lrzip(p_archive);
-    //    archive_read_support_filter_lzip(p_archive);
-    archive_read_support_filter_lzma(p_archive);
-    archive_read_support_filter_lzop(p_archive);
-    archive_read_support_filter_none(p_archive);
-    archive_read_support_filter_rpm(p_archive);
-    archive_read_support_filter_uu(p_archive);
-    archive_read_support_filter_xz(p_archive);
-
-    //    archive_read_support_format_7zip(p_archive);
-    archive_read_support_format_ar(p_archive);
-    archive_read_support_format_cab(p_archive);
-    archive_read_support_format_cpio(p_archive);
-    archive_read_support_format_gnutar(p_archive);
-    //    archive_read_support_format_iso9660(p_archive);
-    archive_read_support_format_lha(p_archive);
-    archive_read_support_format_mtree(p_archive);
-    archive_read_support_format_rar(p_archive);
-    archive_read_support_format_raw(p_archive);
-    archive_read_support_format_tar(p_archive);
-    archive_read_support_format_xar(p_archive);
-    //    archive_read_support_format_zip(p_archive);
-}
diff --git a/modules/access/archive/archive.h b/modules/access/archive/archive.h
deleted file mode 100644
index 4e6d7ccfea..0000000000
--- a/modules/access/archive/archive.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*****************************************************************************
- * archive.h: libarchive access & stream filter
- *****************************************************************************
- * Copyright (C) 2014 Videolan Team
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser 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>
-
-int AccessOpen(vlc_object_t *object);
-void AccessClose(vlc_object_t *object);
-
-int StreamOpen(vlc_object_t *object);
-void StreamClose(vlc_object_t *object);
-
-bool ProbeArchiveFormat(stream_t *p_stream);
-
-struct archive;
-void EnableArchiveFormats(struct archive *p_archive);
-
-#define ARCHIVE_READ_SIZE 8192
-#define ARCHIVE_SEP_CHAR '|'
diff --git a/modules/access/archive/stream.c b/modules/access/archive/stream.c
deleted file mode 100644
index 4d7f3b6919..0000000000
--- a/modules/access/archive/stream.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*****************************************************************************
- * stream.c: libarchive based stream filter
- *****************************************************************************
- * Copyright (C) 2014 Videolan Team
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser 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.
- *****************************************************************************/
-
-#include "archive.h"
-
-#include <vlc_stream.h>
-#include <vlc_url.h>
-#include <vlc_input_item.h>
-
-#include <archive.h>
-#include <archive_entry.h>
-
-struct stream_sys_t
-{
-    struct archive *p_archive;
-    bool b_source_canseek;
-    uint8_t buffer[ARCHIVE_READ_SIZE];
-};
-
-static ssize_t NoRead(stream_t *p_stream, void *buf, size_t len)
-{
-    (void) p_stream; (void) buf; (void) len;
-    return -1;
-}
-
-static int Control(stream_t *p_stream, int i_query, va_list args)
-{
-    switch( i_query )
-    {
-        case STREAM_IS_DIRECTORY:
-            *va_arg( args, bool * ) = false;
-            break;
-
-        case STREAM_CAN_SEEK:
-        case STREAM_CAN_FASTSEEK:
-        case STREAM_GET_SIZE:
-        case STREAM_SET_RECORD_STATE:
-        case STREAM_GET_CONTENT_TYPE:
-            return VLC_EGENERIC;
-
-        default:
-            return vlc_stream_vaControl( p_stream->p_source, i_query, args );
-    }
-
-    return VLC_SUCCESS;
-}
-
-static ssize_t ReadCallback(struct archive *p_archive, void *p_object, const void **pp_buffer)
-{
-    VLC_UNUSED(p_archive);
-    stream_t *p_stream = (stream_t*)p_object;
-    stream_sys_t *sys = p_stream->p_sys;
-
-    *pp_buffer = &sys->buffer;
-    return vlc_stream_Read(p_stream->p_source, &sys->buffer, ARCHIVE_READ_SIZE);
-}
-
-static ssize_t SkipCallback(struct archive *p_archive, void *p_object, ssize_t i_request)
-{
-    VLC_UNUSED(p_archive);
-    stream_t *p_stream = (stream_t*)p_object;
-    stream_sys_t *sys = p_stream->p_sys;
-    ssize_t i_skipped = 0;
-
-    /* be smart as small seeks converts to reads */
-    if (sys->b_source_canseek)
-    {
-        int64_t i_pos = vlc_stream_Tell(p_stream->p_source);
-        if (i_pos >=0)
-            vlc_stream_Seek(p_stream->p_source, i_pos + i_request);
-        i_skipped = vlc_stream_Tell(p_stream->p_source) - i_pos;
-    }
-    else while(i_request)
-    {
-        int i_skip = __MIN(INT32_MAX, i_request);
-        int i_read = vlc_stream_Read(p_stream->p_source, NULL, i_skip);
-        if (i_read > 0)
-            i_skipped += i_read;
-        else
-            break;
-        i_request -= i_read;
-    }
-
-    return i_skipped;
-}
-
-static ssize_t SeekCallback(struct archive *p_archive, void *p_object, ssize_t i_offset, int i_whence)
-{
-    VLC_UNUSED(p_archive);
-    stream_t *p_stream = (stream_t*)p_object;
-    ssize_t i_pos;
-
-    switch(i_whence)
-    {
-    case SEEK_CUR:
-        i_pos = vlc_stream_Tell(p_stream->p_source);
-        break;
-    case SEEK_SET:
-        i_pos = 0;
-        break;
-    case SEEK_END:
-        i_pos = stream_Size(p_stream->p_source) - 1;
-        break;
-    default:
-        return -1;
-    }
-
-    if (i_pos < 0)
-        return -1;
-
-    vlc_stream_Seek(p_stream->p_source, i_pos + i_offset); /* We don't care about return val */
-    return vlc_stream_Tell(p_stream->p_source);
-}
-
-static int Browse(stream_t *p_stream, input_item_node_t *p_node)
-{
-    stream_sys_t *p_sys = p_stream->p_sys;
-    struct archive_entry *p_entry;
-
-    while(archive_read_next_header(p_sys->p_archive, &p_entry) == ARCHIVE_OK)
-    {
-        char *psz_uri = NULL;
-        char *psz_access_uri = NULL;
-        int i_ret = asprintf(&psz_access_uri, "%s%c%s", p_stream->psz_url,
-                             ARCHIVE_SEP_CHAR, archive_entry_pathname(p_entry));
-        if (i_ret == -1)
-            goto error;
-        i_ret = asprintf(&psz_uri, "archive://%s", psz_access_uri);
-        free(psz_access_uri);
-        if(i_ret == -1)
-            goto error;
-
-        input_item_t *p_item = input_item_New(psz_uri, archive_entry_pathname(p_entry));
-        free( psz_uri );
-        if (p_item == NULL)
-            goto error;
-
-        input_item_CopyOptions(p_node->p_item, p_item);
-        input_item_node_AppendItem(p_node, p_item);
-        msg_Dbg(p_stream, "declaring playlist entry %s", archive_entry_pathname(p_entry));
-        input_item_Release(p_item);
-    }
-
-    return VLC_SUCCESS;
-
-error:
-    return VLC_ENOMEM;
-}
-
-int StreamOpen(vlc_object_t *p_object)
-{
-    stream_t *p_stream = (stream_t*) p_object;
-    stream_sys_t *p_sys;
-
-    if (!ProbeArchiveFormat(p_stream->p_source))
-        return VLC_EGENERIC;
-    if (p_stream->psz_url == NULL)
-        return VLC_EGENERIC;
-
-    p_stream->p_sys = p_sys = calloc( 1, sizeof( *p_sys ) );
-    if( !p_sys )
-        return VLC_ENOMEM;
-
-    p_sys->p_archive = archive_read_new();
-    if (!p_sys->p_archive)
-    {
-        msg_Err(p_stream, "can't create libarchive instance: %s",
-                archive_error_string(p_sys->p_archive));
-        StreamClose(p_object);
-        return VLC_EGENERIC;
-    }
-
-    EnableArchiveFormats(p_sys->p_archive);
-
-    /* Seek callback must only be set if calls are guaranteed to succeed */
-    vlc_stream_Control(p_stream->p_source, STREAM_CAN_SEEK,
-                       &p_sys->b_source_canseek);
-    if(p_sys->b_source_canseek)
-        archive_read_set_seek_callback(p_sys->p_archive, SeekCallback);
-
-    if (archive_read_open2(p_sys->p_archive, p_stream, NULL, ReadCallback, SkipCallback, NULL) != ARCHIVE_OK)
-    {
-        msg_Err(p_stream, "can't open archive: %s",
-                archive_error_string(p_sys->p_archive));
-        StreamClose(p_object);
-        return VLC_EGENERIC;
-    }
-
-    p_stream->pf_read = NoRead;
-    p_stream->pf_seek = NULL;
-    p_stream->pf_control = Control;
-    p_stream->pf_readdir = Browse;
-
-    return VLC_SUCCESS;
-}
-
-void StreamClose(vlc_object_t *object)
-{
-    stream_t *p_stream = (stream_t*)object;
-    stream_sys_t *p_sys = p_stream->p_sys;
-
-    if (p_sys->p_archive)
-    {
-        archive_read_close(p_sys->p_archive);
-        archive_read_free(p_sys->p_archive);
-    }
-
-    free(p_sys);
-}
-- 
2.11.1

