Back to index

avfs  1.0.1
Classes | Defines | Functions | Variables
xzread.c File Reference
#include "config.h"
#include "xzfile.h"
#include "lzma.h"
#include "oper.h"
#include "exit.h"
#include <stdlib.h>
#include <fcntl.h>

Go to the source code of this file.

Classes

struct  xzstreamcache
struct  xzcache
struct  xzfile

Defines

#define INBUFSIZE   16384
#define OUTBUFSIZE   32768
#define INITIAL_MEMLIMIT   (100<<20)

Functions

static AV_LOCK_DECL (xzread_lock)
void xz_internal_error (int errorcode)
static avoff_t xz_total_in (lzma_stream *s)
static avoff_t xz_total_out (lzma_stream *s)
static void xz_delete_stream (lzma_stream *s)
static int xz_new_stream (lzma_stream **resp)
static void xzfile_scache_delete ()
static void xzfile_scache_save (int id, lzma_stream *s)
static int xzfile_reset (struct xzfile *fil)
static int xzfile_fill_inbuf (struct xzfile *fil)
static int xzfile_decompress (struct xzfile *fil, struct xzcache *zc)
static int xzfile_read (struct xzfile *fil, struct xzcache *zc, char *buf, avsize_t nbyte)
static int xzfile_skip_to (struct xzfile *fil, struct xzcache *zc, avoff_t offset)
static avssize_t av_xzfile_do_pread (struct xzfile *fil, struct xzcache *zc, char *buf, avsize_t nbyte, avoff_t offset)
avssize_t av_xzfile_pread (struct xzfile *fil, struct xzcache *zc, char *buf, avsize_t nbyte, avoff_t offset)
int av_xzfile_size (struct xzfile *fil, struct xzcache *zc, avoff_t *sizep)
static void xzfile_destroy (struct xzfile *fil)
struct xzfileav_xzfile_new (vfile *vf)
static void xzcache_destroy (struct xzcache *zc)
struct xzcacheav_xzcache_new ()

Variables

static struct xzstreamcache
static int xzread_nextid

Class Documentation

struct xzstreamcache

Definition at line 25 of file xzread.c.

Class Members
int id
lzma_stream * s
struct xzcache

Definition at line 37 of file xzread.c.

Class Members
int id
avoff_t size
struct xzfile

Definition at line 42 of file xzread.c.

Class Members
int id
char inbuf
vfile * infile
int iseof
int iserror
lzma_stream * s

Define Documentation

#define INBUFSIZE   16384

Definition at line 21 of file xzread.c.

#define INITIAL_MEMLIMIT   (100<<20)

Definition at line 23 of file xzread.c.

#define OUTBUFSIZE   32768

Definition at line 22 of file xzread.c.


Function Documentation

static AV_LOCK_DECL ( xzread_lock  ) [static]
struct xzcache* av_xzcache_new ( ) [read]

Definition at line 345 of file xzread.c.

{
    struct xzcache *zc;

    AV_NEW_OBJ(zc, xzcache_destroy);
    zc->size = -1;

    AV_LOCK(xzread_lock);
    if(xzread_nextid == 0)
        xzread_nextid = 1;

    zc->id = xzread_nextid ++;
    AV_UNLOCK(xzread_lock);
    
    return zc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static avssize_t av_xzfile_do_pread ( struct xzfile fil,
struct xzcache zc,
char *  buf,
avsize_t  nbyte,
avoff_t  offset 
) [static]

Definition at line 232 of file xzread.c.

{
    avssize_t res;
    avoff_t curroff;

    fil->id = zc->id;

    curroff = xz_total_out(fil->s);
    if(offset != curroff) {
        AV_LOCK(xzread_lock);
        if ( curroff > offset ) {
            res = xzfile_reset( fil );
        } else {
            res = 0;
        }
        AV_UNLOCK(xzread_lock);
        if(res < 0)
            return res;

        res = xzfile_skip_to(fil, zc, offset);
        if(res < 0)
            return res;
    }

    res = xzfile_read(fil, zc, buf, nbyte);
    
    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct xzfile* av_xzfile_new ( vfile *  vf) [read]

Definition at line 323 of file xzread.c.

{
    int res;
    struct xzfile *fil;

    AV_NEW_OBJ(fil, xzfile_destroy);
    fil->iseof = 0;
    fil->iserror = 0;
    fil->infile = vf;
    fil->id = 0;

    res = xz_new_stream(&fil->s);
    if(res < 0)
        fil->iserror = 1;

    return fil;
}

Here is the call graph for this function:

Here is the caller graph for this function:

avssize_t av_xzfile_pread ( struct xzfile fil,
struct xzcache zc,
char *  buf,
avsize_t  nbyte,
avoff_t  offset 
)

Definition at line 262 of file xzread.c.

{
    avssize_t res;

    if(fil->iserror)
        return -EIO;

    res = av_xzfile_do_pread(fil, zc, buf, nbyte, offset);
    if(res < 0)
        fil->iserror = 1;

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int av_xzfile_size ( struct xzfile fil,
struct xzcache zc,
avoff_t sizep 
)

Definition at line 277 of file xzread.c.

{
    int res;
    avoff_t size;

    AV_LOCK(xzread_lock);
    size = zc->size;
    AV_UNLOCK(xzread_lock);

    if(size != -1 || fil == NULL) {
        *sizep = size;
        return 0;
    }

    fil->id = zc->id;

    AV_LOCK(xzread_lock);
    res = xzfile_reset( fil );
    AV_UNLOCK(xzread_lock);
    if(res < 0)
        return res;

    res = xzfile_skip_to(fil, zc, AV_MAXOFF);
    if(res < 0)
        return res;
    
    AV_LOCK(xzread_lock);
    size = zc->size;
    AV_UNLOCK(xzread_lock);
    
    if(size == -1) {
        av_log(AVLOG_ERROR, "XZ: Internal error: could not find size");
        return -EIO;
    }
    
    *sizep = size;
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void xz_delete_stream ( lzma_stream *  s) [static]

Definition at line 67 of file xzread.c.

{
    if(s != NULL) {
        lzma_end(s);
        
        av_free(s);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void xz_internal_error ( int  errorcode)

Definition at line 52 of file xzread.c.

{
    av_log(AVLOG_ERROR, "XZ: internal error %i", errorcode);
}

Here is the call graph for this function:

static int xz_new_stream ( lzma_stream **  resp) [static]

Definition at line 76 of file xzread.c.

{
    int res;
    lzma_stream *s;
    lzma_stream tmp = LZMA_STREAM_INIT;

    AV_NEW(s);
    *s = tmp;

    /* TODO: choose good memory limit */
    res = lzma_auto_decoder(s, INITIAL_MEMLIMIT, 0);
    if(res != LZMA_OK) {
        *resp = NULL;
        av_log(AVLOG_ERROR, "XZ: decompress init error: %i", res);
        return -EIO;
    }

    *resp = s;
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static avoff_t xz_total_in ( lzma_stream *  s) [static]

Definition at line 57 of file xzread.c.

{
    return (avoff_t) s->total_in;
}

Here is the caller graph for this function:

static avoff_t xz_total_out ( lzma_stream *  s) [static]

Definition at line 62 of file xzread.c.

{
    return (avoff_t) s->total_out;
}

Here is the caller graph for this function:

static void xzcache_destroy ( struct xzcache zc) [static]

Definition at line 341 of file xzread.c.

{
}

Here is the caller graph for this function:

static int xzfile_decompress ( struct xzfile fil,
struct xzcache zc 
) [static]

Definition at line 155 of file xzread.c.

{
    int res;
    unsigned char *start;

    if(fil->s->avail_in == 0) {
        res = xzfile_fill_inbuf(fil);
        if(res < 0)
            return res;
       if(fil->s->avail_in == 0) {
         /* still no byte available */
         av_log(AVLOG_ERROR, "XZ: decompress error");
         return -EIO;
       }
    }
    
    start = (unsigned char*)( fil->s->next_out );

    res = lzma_code(fil->s, LZMA_RUN);
    if(res == LZMA_STREAM_END) {
        fil->iseof = 1;
        AV_LOCK(xzread_lock);
        zc->size = xz_total_out(fil->s);
        AV_UNLOCK(xzread_lock);
        return 0;
    }
    /*TODO handle LZMA_MEMLIMIT_ERROR */
    if(res != LZMA_OK) {
        av_log(AVLOG_ERROR, "XZ: decompress error: %i", res);
        return -EIO;
    }
    /*TODO what if avail_in is not 0? */
    
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void xzfile_destroy ( struct xzfile fil) [static]

Definition at line 316 of file xzread.c.

{
    AV_LOCK(xzread_lock);
    xzfile_scache_save(fil->id, fil->s);
    AV_UNLOCK(xzread_lock);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int xzfile_fill_inbuf ( struct xzfile fil) [static]

Definition at line 140 of file xzread.c.

{
    avssize_t res;
    avoff_t inoff = xz_total_in(fil->s);

    res = av_pread(fil->infile, fil->inbuf, INBUFSIZE, inoff);
    if(res < 0)
        return res;
    
    fil->s->next_in = (uint8_t*)fil->inbuf;
    fil->s->avail_in = res;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int xzfile_read ( struct xzfile fil,
struct xzcache zc,
char *  buf,
avsize_t  nbyte 
) [static]

Definition at line 192 of file xzread.c.

{
    int res;

    fil->s->next_out = (uint8_t*)buf;
    fil->s->avail_out = nbyte;
    while(fil->s->avail_out != 0 && !fil->iseof) {
        res = xzfile_decompress(fil, zc);
        if(res < 0)
            return res;
    }

    return nbyte - fil->s->avail_out;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int xzfile_reset ( struct xzfile fil) [static]

Definition at line 127 of file xzread.c.

{
    /* FIXME: Is it a good idea to save the previous state or not? */
    if (fil->iseof || fil->iserror)
        xz_delete_stream(fil->s);
    else
        xzfile_scache_save(fil->id, fil->s);

    fil->iseof = 0;
    fil->iserror = 0;
    return xz_new_stream(&fil->s);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void xzfile_scache_delete ( ) [static]

Definition at line 97 of file xzread.c.

{
    AV_LOCK(xzread_lock);
    if(xzscache.id != 0) {
        xz_delete_stream(xzscache.s);
        xzscache.id = 0;
    }
    AV_UNLOCK(xzread_lock);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void xzfile_scache_save ( int  id,
lzma_stream *  s 
) [static]

Definition at line 107 of file xzread.c.

{
    static int regdestroy = 0;
    if(!regdestroy) {
        regdestroy = 1;
        av_add_exithandler(xzfile_scache_delete);
    }

    if(id == 0 || s == NULL) {
        xz_delete_stream(s);
        return;
    }
    
    if(xzscache.id != 0)
        xz_delete_stream(xzscache.s);

    xzscache.id = id;
    xzscache.s = s;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int xzfile_skip_to ( struct xzfile fil,
struct xzcache zc,
avoff_t  offset 
) [static]

Definition at line 208 of file xzread.c.

{
    int res;
    uint8_t outbuf[OUTBUFSIZE];
    
    while(!fil->iseof) {
        avoff_t curroff = xz_total_out(fil->s);

        if(curroff == offset)
            break;

        /* FIXME: Maybe cache some data as well */
        fil->s->next_out = outbuf;
        fil->s->avail_out = AV_MIN(OUTBUFSIZE, offset - curroff);

        res = xzfile_decompress(fil, zc);
        if(res < 0)
            return res;
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

int xzread_nextid [static]

Definition at line 34 of file xzread.c.

struct xzstreamcache [static]

Definition at line 33 of file xzread.c.