/* xzio.c - decompression support for xz */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2010 Free Software Foundation, Inc.
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
GRUB_MOD_LICENSE ("GPLv3+");
#include "xz.h"
#include "xz_stream.h"
struct grub_xzio
{
};
static grub_size_t
{
if (size_max == 0)
return 0;
if (size_max > VLI_MAX_DIGITS)
grub_size_t i = 0;
while (buf[i++] & 0x80)
{
return 0;
}
return i;
}
static grub_ssize_t
{
if (read < 0)
return -1;
return dec;
}
/* Function xz_dec_run() should consume header and ask for more (XZ_OK)
* else file is corrupted (or options not supported) or not xz. */
static int
{
{
return 0;
}
if (ret == XZ_FORMAT_ERROR)
{
return 0;
}
{
return 0;
}
return 1;
}
/* Try to find out size of uncompressed data,
* also do some footer sanity checks. */
static int
{
goto ERROR;
!= sizeof (backsize))
goto ERROR;
/* Calculate real backward size. */
/* Set file to the beginning of stream index. */
/* Test index marker. */
goto ERROR;
goto ERROR;
{
goto ERROR;
goto ERROR;
}
return 1;
return 0;
}
static grub_file_t
{
if (!file)
return 0;
if (!xzio)
{
return 0;
}
xzio->saved_offset = 0;
/* Allocated 64KiB for dictionary.
* Decoder will relocate if bigger is needed. */
{
return 0;
}
/* FIXME: don't test footer on not easily seekable files. */
{
grub_file_seek (io, 0);
return io;
}
return file;
}
static grub_ssize_t
{
/* If seek backward need to reset decoder and start from beginning of file.
TODO Possible improvement by jumping blocks. */
{
xzio->saved_offset = 0;
}
while (len > 0)
{
/* Feed input. */
{
if (readret < 0)
return -1;
}
switch (xzret)
{
case XZ_MEMLIMIT_ERROR:
case XZ_FORMAT_ERROR:
case XZ_OPTIONS_ERROR:
case XZ_DATA_ERROR:
case XZ_BUF_ERROR:
"file corrupted or unsupported block options");
return -1;
default:
break;
}
{
/* Store first chunk of data in buffer. */
{
delta);
}
}
break;
}
if (ret >= 0)
return ret;
}
/* Release everything, including the underlying file object. */
static grub_err_t
{
/* Device must not be closed twice. */
return grub_errno;
}
.name = "xzio",
.dir = 0,
.open = 0,
.read = grub_xzio_read,
.close = grub_xzio_close,
.label = 0,
.next = 0
};
{
}
{
}