add 3rdparty/xdelta3-3.0.8

This commit is contained in:
josch
2014-11-03 20:35:23 +01:00
parent 720d5da086
commit 070c7fdc3e
17 changed files with 20286 additions and 0 deletions

340
3rdparty/xdelta3-3.0.8/COPYING vendored Normal file
View File

@@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

34
3rdparty/xdelta3-3.0.8/README vendored Normal file
View File

@@ -0,0 +1,34 @@
Xdelta 3.x readme.txt
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
<josh.macdonald@gmail.com>
Thanks for downloading Xdelta!
This directory contains the Xdelta3 command-line interface (CLI) and source
distribution for VCDIFF differential compression, a.k.a. delta
compression. The latest information and downloads are available here:
http://xdelta.org/
http://code.google.com/p/xdelta/
The command-line syntax:
http://code.google.com/p/xdelta/wiki/CommandLineSyntax
Run 'xdelta3 -h' for brief help. Run 'xdelta3 test' for built-in tests.
Sample commands (like gzip, -e means encode, -d means decode)
xdelta3 -9 -S djw -e -vfs OLD_FILE NEW_FILE DELTA_FILE
xdelta3 -d -vfs OLD_FILE DELTA_FILE DECODED_FILE
File bug reports and browse open support issues here:
http://code.google.com/p/xdelta/issues/list
The source distribution contains the C/C++/Python APIs, Unix, Microsoft VC++
and Cygwin builds. Xdelta3 is covered under the terms of the GPL, see
COPYING.
Commercial inquiries welcome, please contact <josh.macdonald@gmail.com>

View File

@@ -0,0 +1,569 @@
/* xdelta 3 - delta compression tools and library
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007,
* 2008, 2009, 2010
* Joshua P. MacDonald
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* TODO: This code is heavily revised from 3.0z but still needs major
* refactoring. */
#include "xdelta3-internal.h"
typedef struct _main_blklru main_blklru;
typedef struct _main_blklru_list main_blklru_list;
struct _main_blklru_list
{
main_blklru_list *next;
main_blklru_list *prev;
};
struct _main_blklru
{
uint8_t *blk;
xoff_t blkno;
usize_t size;
main_blklru_list link;
};
#define MAX_LRU_SIZE 32U
#define XD3_MINSRCWINSZ (XD3_ALLOCSIZE * MAX_LRU_SIZE)
#define XD3_MAXSRCWINSZ (1ULL << 31)
XD3_MAKELIST(main_blklru_list,main_blklru,link);
static usize_t lru_size = 0;
static main_blklru *lru = NULL; /* array of lru_size elts */
static main_blklru_list lru_list;
static int do_src_fifo = 0; /* set to avoid lru */
static int lru_hits = 0;
static int lru_misses = 0;
static int lru_filled = 0;
static void main_lru_reset (void)
{
lru_size = 0;
lru = NULL;
do_src_fifo = 0;
lru_hits = 0;
lru_misses = 0;
lru_filled = 0;
}
static void main_lru_cleanup (void)
{
if (lru != NULL)
{
main_buffree (lru[0].blk);
}
main_free (lru);
lru = NULL;
lru_hits = 0;
lru_misses = 0;
lru_filled = 0;
}
/* This is called at different times for encoding and decoding. The
* encoder calls it immediately, the decoder delays until the
* application header is received. */
static int
main_set_source (xd3_stream *stream, xd3_cmd cmd,
main_file *sfile, xd3_source *source)
{
int ret = 0;
usize_t i;
xoff_t source_size = 0;
usize_t blksize;
XD3_ASSERT (lru == NULL);
XD3_ASSERT (stream->src == NULL);
XD3_ASSERT (option_srcwinsz >= XD3_MINSRCWINSZ);
/* TODO: this code needs refactoring into FIFO, LRU, FAKE. Yuck!
* This is simplified from 3.0z which had issues with sizing the
* source buffer memory allocation and the source blocksize. */
/* LRU-specific */
main_blklru_list_init (& lru_list);
if (allow_fake_source)
{
/* TODO: refactor
* TOOLS/recode-specific: Check "allow_fake_source" mode looks
* broken now. */
sfile->mode = XO_READ;
sfile->realname = sfile->filename;
sfile->nread = 0;
}
else
{
/* Either a regular file (possibly compressed) or a FIFO
* (possibly compressed). */
if ((ret = main_file_open (sfile, sfile->filename, XO_READ)))
{
return ret;
}
/* If the file is regular we know it's size. If the file turns
* out to be externally compressed, size_known may change. */
sfile->size_known = (main_file_stat (sfile, &source_size) == 0);
}
/* Note: The API requires a power-of-two blocksize and srcwinsz
* (-B). The logic here will use a single block if the entire file
* is known to fit into srcwinsz. */
option_srcwinsz = xd3_pow2_roundup (option_srcwinsz);
/* Though called "lru", it is not LRU-specific. We always allocate
* a maximum number of source block buffers. If the entire file
* fits into srcwinsz, this buffer will stay as the only
* (lru_size==1) source block. Otherwise, we know that at least
* option_srcwinsz bytes are available. Split the source window
* into buffers. */
if ((lru = (main_blklru*) main_malloc (MAX_LRU_SIZE *
sizeof (main_blklru))) == NULL)
{
ret = ENOMEM;
return ret;
}
memset (lru, 0, sizeof(lru[0]) * MAX_LRU_SIZE);
/* Allocate the entire buffer. */
if ((lru[0].blk = (uint8_t*) main_bufalloc (option_srcwinsz)) == NULL)
{
ret = ENOMEM;
return ret;
}
/* Main calls main_getblk_func() once before xd3_set_source(). This
* is the point at which external decompression may begin. Set the
* system for a single block. */
lru_size = 1;
lru[0].blkno = (xoff_t) -1;
blksize = option_srcwinsz;
main_blklru_list_push_back (& lru_list, & lru[0]);
XD3_ASSERT (blksize != 0);
/* Initialize xd3_source. */
source->blksize = blksize;
source->name = sfile->filename;
source->ioh = sfile;
source->curblkno = (xoff_t) -1;
source->curblk = NULL;
source->max_winsize = option_srcwinsz;
if ((ret = main_getblk_func (stream, source, 0)) != 0)
{
XPR(NT "error reading source: %s: %s\n",
sfile->filename,
xd3_mainerror (ret));
return ret;
}
source->onblk = lru[0].size; /* xd3 sets onblk */
/* If the file is smaller than a block, size is known. */
if (!sfile->size_known && source->onblk < blksize)
{
source_size = source->onblk;
sfile->size_known = 1;
}
/* If the size is not known or is greater than the buffer size, we
* split the buffer across MAX_LRU_SIZE blocks (already allocated in
* "lru"). */
if (!sfile->size_known || source_size > option_srcwinsz)
{
/* Modify block 0, change blocksize. */
blksize = option_srcwinsz / MAX_LRU_SIZE;
source->blksize = blksize;
source->onblk = blksize; /* xd3 sets onblk */
/* Note: source->max_winsize is unchanged. */
lru[0].size = blksize;
lru_size = MAX_LRU_SIZE;
/* Setup rest of blocks. */
for (i = 1; i < lru_size; i += 1)
{
lru[i].blk = lru[0].blk + (blksize * i);
lru[i].blkno = i;
lru[i].size = blksize;
main_blklru_list_push_back (& lru_list, & lru[i]);
}
}
if (! sfile->size_known)
{
/* If the size is not know, we must use FIFO discipline. */
do_src_fifo = 1;
}
/* Call the appropriate set_source method, handle errors, print
* verbose message, etc. */
if (sfile->size_known)
{
ret = xd3_set_source_and_size (stream, source, source_size);
}
else
{
ret = xd3_set_source (stream, source);
}
if (ret)
{
XPR(NT XD3_LIB_ERRMSG (stream, ret));
return ret;
}
XD3_ASSERT (stream->src == source);
XD3_ASSERT (source->blksize == blksize);
if (option_verbose)
{
static shortbuf srcszbuf;
static shortbuf srccntbuf;
static shortbuf winszbuf;
static shortbuf blkszbuf;
static shortbuf nbufs;
if (sfile->size_known)
{
short_sprintf (srcszbuf, "source size %s [%"Q"u]",
main_format_bcnt (source_size, &srccntbuf),
source_size);
}
else
{
short_sprintf (srcszbuf, "%s", "source size unknown");
}
nbufs.buf[0] = 0;
if (option_verbose > 1)
{
short_sprintf (nbufs, " #bufs %u", lru_size);
}
XPR(NT "source %s %s blksize %s window %s%s%s\n",
sfile->filename,
srcszbuf.buf,
main_format_bcnt (blksize, &blkszbuf),
main_format_bcnt (option_srcwinsz, &winszbuf),
nbufs.buf,
do_src_fifo ? " (FIFO)" : "");
}
return 0;
}
static int
main_getblk_lru (xd3_source *source, xoff_t blkno,
main_blklru** blrup, int *is_new)
{
main_blklru *blru = NULL;
usize_t i;
(*is_new) = 0;
if (do_src_fifo)
{
/* Direct lookup assumes sequential scan w/o skipping blocks. */
int idx = blkno % lru_size;
blru = & lru[idx];
if (blru->blkno == blkno)
{
(*blrup) = blru;
return 0;
}
/* No going backwards in a sequential scan. */
if (blru->blkno != (xoff_t) -1 && blru->blkno > blkno)
{
return XD3_TOOFARBACK;
}
}
else
{
/* Sequential search through LRU. */
for (i = 0; i < lru_size; i += 1)
{
blru = & lru[i];
if (blru->blkno == blkno)
{
main_blklru_list_remove (blru);
main_blklru_list_push_back (& lru_list, blru);
(*blrup) = blru;
return 0;
}
}
}
if (do_src_fifo)
{
int idx = blkno % lru_size;
blru = & lru[idx];
}
else
{
XD3_ASSERT (! main_blklru_list_empty (& lru_list));
blru = main_blklru_list_pop_front (& lru_list);
main_blklru_list_push_back (& lru_list, blru);
}
lru_filled += 1;
(*is_new) = 1;
(*blrup) = blru;
blru->blkno = -1;
return 0;
}
static int
main_read_seek_source (xd3_stream *stream,
xd3_source *source,
xoff_t blkno) {
xoff_t pos = blkno * source->blksize;
main_file *sfile = (main_file*) source->ioh;
main_blklru *blru;
int is_new;
size_t nread = 0;
int ret = 0;
if (!sfile->seek_failed)
{
ret = main_file_seek (sfile, pos);
if (ret == 0)
{
sfile->source_position = pos;
}
}
if (sfile->seek_failed || ret != 0)
{
/* For an unseekable file (or other seek error, does it
* matter?) */
if (sfile->source_position > pos)
{
/* Could assert !IS_ENCODE(), this shouldn't happen
* because of do_src_fifo during encode. */
if (!option_quiet)
{
XPR(NT "source can't seek backwards; requested block offset "
"%"Q"u source position is %"Q"u\n",
pos, sfile->source_position);
}
sfile->seek_failed = 1;
stream->msg = "non-seekable source: "
"copy is too far back (try raising -B)";
return XD3_TOOFARBACK;
}
/* There's a chance here, that an genuine lseek error will cause
* xdelta3 to shift into non-seekable mode, entering a degraded
* condition. */
if (!sfile->seek_failed && option_verbose)
{
XPR(NT "source can't seek, will use FIFO for %s\n",
sfile->filename);
if (option_verbose > 1)
{
XPR(NT "seek error at offset %"Q"u: %s\n",
pos, xd3_mainerror (ret));
}
}
sfile->seek_failed = 1;
if (option_verbose > 1 && pos != sfile->source_position)
{
XPR(NT "non-seekable source skipping %"Q"u bytes @ %"Q"u\n",
pos - sfile->source_position,
sfile->source_position);
}
while (sfile->source_position < pos)
{
xoff_t skip_blkno;
usize_t skip_offset;
xd3_blksize_div (sfile->source_position, source,
&skip_blkno, &skip_offset);
/* Read past unused data */
XD3_ASSERT (pos - sfile->source_position >= source->blksize);
XD3_ASSERT (skip_offset == 0);
if ((ret = main_getblk_lru (source, skip_blkno,
& blru, & is_new)))
{
return ret;
}
XD3_ASSERT (is_new);
blru->blkno = skip_blkno;
if ((ret = main_read_primary_input (sfile,
(uint8_t*) blru->blk,
source->blksize,
& nread)))
{
return ret;
}
if (nread != source->blksize)
{
IF_DEBUG1 (DP(RINT "[getblk] short skip block nread = %zu\n",
nread));
stream->msg = "non-seekable input is short";
return XD3_INVALID_INPUT;
}
sfile->source_position += nread;
blru->size = nread;
IF_DEBUG1 (DP(RINT "[getblk] skip blkno %"Q"u size %u\n",
skip_blkno, blru->size));
XD3_ASSERT (sfile->source_position <= pos);
}
}
return 0;
}
/* This is the callback for reading a block of source. This function
* is blocking and it implements a small LRU.
*
* Note that it is possible for main_input() to handle getblk requests
* in a non-blocking manner. If the callback is NULL then the caller
* of xd3_*_input() must handle the XD3_GETSRCBLK return value and
* fill the source in the same way. See xd3_getblk for details. To
* see an example of non-blocking getblk, see xdelta-test.h. */
static int
main_getblk_func (xd3_stream *stream,
xd3_source *source,
xoff_t blkno)
{
int ret = 0;
xoff_t pos = blkno * source->blksize;
main_file *sfile = (main_file*) source->ioh;
main_blklru *blru;
int is_new;
int did_seek = 0;
size_t nread = 0;
if (allow_fake_source)
{
source->curblkno = blkno;
source->onblk = 0;
source->curblk = lru[0].blk;
lru[0].size = 0;
return 0;
}
if ((ret = main_getblk_lru (source, blkno, & blru, & is_new)))
{
return ret;
}
if (!is_new)
{
source->curblkno = blkno;
source->onblk = blru->size;
source->curblk = blru->blk;
lru_hits++;
return 0;
}
lru_misses += 1;
if (pos != sfile->source_position)
{
/* Only try to seek when the position is wrong. This means the
* decoder will fail when the source buffer is too small, but
* only when the input is non-seekable. */
if ((ret = main_read_seek_source (stream, source, blkno)))
{
return ret;
}
/* Indicates that another call to main_getblk_lru() may be
* needed */
did_seek = 1;
}
XD3_ASSERT (sfile->source_position == pos);
if (did_seek &&
(ret = main_getblk_lru (source, blkno, & blru, & is_new)))
{
return ret;
}
if ((ret = main_read_primary_input (sfile,
(uint8_t*) blru->blk,
source->blksize,
& nread)))
{
return ret;
}
/* Save the last block read, used to handle non-seekable files. */
sfile->source_position = pos + nread;
if (option_verbose > 3)
{
if (blru->blkno != (xoff_t)-1)
{
if (blru->blkno != blkno)
{
XPR(NT "source block %"Q"u read %zu ejects %"Q"u (lru_hits=%u, "
"lru_misses=%u, lru_filled=%u)\n",
blkno, nread, blru->blkno, lru_hits, lru_misses, lru_filled);
}
else
{
XPR(NT "source block %"Q"u read %zu (lru_hits=%u, "
"lru_misses=%u, lru_filled=%u)\n",
blkno, nread, lru_hits, lru_misses, lru_filled);
}
}
else
{
XPR(NT "source block %"Q"u read %zu (lru_hits=%u, lru_misses=%u, "
"lru_filled=%u)\n", blkno, nread,
lru_hits, lru_misses, lru_filled);
}
}
source->curblk = blru->blk;
source->curblkno = blkno;
source->onblk = nread;
blru->size = nread;
blru->blkno = blkno;
IF_DEBUG1 (DP(RINT "[main_getblk] blkno %"Q"u onblk %zu pos %"Q"u "
"srcpos %"Q"u\n",
blkno, nread, pos, sfile->source_position));
return 0;
}

173
3rdparty/xdelta3-3.0.8/xdelta3-cfgs.h vendored Normal file
View File

@@ -0,0 +1,173 @@
/* xdelta 3 - delta compression tools and library
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007. Joshua P. MacDonald
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/******************************************************************
SOFT string matcher
******************************************************************/
#if XD3_BUILD_SOFT
#define TEMPLATE soft
#define LLOOK stream->smatcher.large_look
#define LSTEP stream->smatcher.large_step
#define SLOOK stream->smatcher.small_look
#define SCHAIN stream->smatcher.small_chain
#define SLCHAIN stream->smatcher.small_lchain
#define MAXLAZY stream->smatcher.max_lazy
#define LONGENOUGH stream->smatcher.long_enough
#define SOFTCFG 1
#include "xdelta3.c"
#undef SOFTCFG
#undef TEMPLATE
#undef LLOOK
#undef SLOOK
#undef LSTEP
#undef SCHAIN
#undef SLCHAIN
#undef MAXLAZY
#undef LONGENOUGH
#endif
#define SOFTCFG 0
/************************************************************
FASTEST string matcher
**********************************************************/
#if XD3_BUILD_FASTEST
#define TEMPLATE fastest
#define LLOOK 9
#define LSTEP 26
#define SLOOK 4U
#define SCHAIN 1
#define SLCHAIN 1
#define MAXLAZY 6
#define LONGENOUGH 6
#include "xdelta3.c"
#undef TEMPLATE
#undef LLOOK
#undef SLOOK
#undef LSTEP
#undef SCHAIN
#undef SLCHAIN
#undef MAXLAZY
#undef LONGENOUGH
#endif
/************************************************************
FASTER string matcher
**********************************************************/
#if XD3_BUILD_FASTER
#define TEMPLATE faster
#define LLOOK 9
#define LSTEP 15
#define SLOOK 4U
#define SCHAIN 1
#define SLCHAIN 1
#define MAXLAZY 18
#define LONGENOUGH 18
#include "xdelta3.c"
#undef TEMPLATE
#undef LLOOK
#undef SLOOK
#undef LSTEP
#undef SCHAIN
#undef SLCHAIN
#undef MAXLAZY
#undef LONGENOUGH
#endif
/******************************************************
FAST string matcher
********************************************************/
#if XD3_BUILD_FAST
#define TEMPLATE fast
#define LLOOK 9
#define LSTEP 8
#define SLOOK 4U
#define SCHAIN 4
#define SLCHAIN 1
#define MAXLAZY 18
#define LONGENOUGH 35
#include "xdelta3.c"
#undef TEMPLATE
#undef LLOOK
#undef SLOOK
#undef LSTEP
#undef SCHAIN
#undef SLCHAIN
#undef MAXLAZY
#undef LONGENOUGH
#endif
/**************************************************
SLOW string matcher
**************************************************************/
#if XD3_BUILD_SLOW
#define TEMPLATE slow
#define LLOOK 9
#define LSTEP 2
#define SLOOK 4U
#define SCHAIN 44
#define SLCHAIN 13
#define MAXLAZY 90
#define LONGENOUGH 70
#include "xdelta3.c"
#undef TEMPLATE
#undef LLOOK
#undef SLOOK
#undef LSTEP
#undef SCHAIN
#undef SLCHAIN
#undef MAXLAZY
#undef LONGENOUGH
#endif
/********************************************************
DEFAULT string matcher
************************************************************/
#if XD3_BUILD_DEFAULT
#define TEMPLATE default
#define LLOOK 9
#define LSTEP 3
#define SLOOK 4U
#define SCHAIN 8
#define SLCHAIN 2
#define MAXLAZY 36
#define LONGENOUGH 70
#include "xdelta3.c"
#undef TEMPLATE
#undef LLOOK
#undef SLOOK
#undef LSTEP
#undef SCHAIN
#undef SLCHAIN
#undef MAXLAZY
#undef LONGENOUGH
#endif

1148
3rdparty/xdelta3-3.0.8/xdelta3-decode.h vendored Normal file

File diff suppressed because it is too large Load Diff

1837
3rdparty/xdelta3-3.0.8/xdelta3-djw.h vendored Normal file

File diff suppressed because it is too large Load Diff

860
3rdparty/xdelta3-3.0.8/xdelta3-fgk.h vendored Normal file
View File

@@ -0,0 +1,860 @@
/* xdelta 3 - delta compression tools and library
* Copyright (C) 2002, 2006, 2007. Joshua P. MacDonald
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* For demonstration purposes only.
*/
#ifndef _XDELTA3_FGK_h_
#define _XDELTA3_FGK_h_
/* An implementation of the FGK algorithm described by D.E. Knuth in
* "Dynamic Huffman Coding" in Journal of Algorithms 6. */
/* A 32bit counter (fgk_weight) is used as the frequency counter for
* nodes in the huffman tree. TODO: Need oto test for overflow and/or
* reset stats. */
typedef struct _fgk_stream fgk_stream;
typedef struct _fgk_node fgk_node;
typedef struct _fgk_block fgk_block;
typedef unsigned int fgk_bit;
typedef uint32_t fgk_weight;
struct _fgk_block {
union {
fgk_node *un_leader;
fgk_block *un_freeptr;
} un;
};
#define block_leader un.un_leader
#define block_freeptr un.un_freeptr
/* The code can also support fixed huffman encoding/decoding. */
#define IS_ADAPTIVE 1
/* weight is a count of the number of times this element has been seen
* in the current encoding/decoding. parent, right_child, and
* left_child are pointers defining the tree structure. right and
* left point to neighbors in an ordered sequence of weights. The
* left child of a node is always guaranteed to have weight not
* greater than its sibling. fgk_blockLeader points to the element
* with the same weight as itself which is closest to the next
* increasing weight block. */
struct _fgk_node
{
fgk_weight weight;
fgk_node *parent;
fgk_node *left_child;
fgk_node *right_child;
fgk_node *left;
fgk_node *right;
fgk_block *my_block;
};
/* alphabet_size is the a count of the number of possible leaves in
* the huffman tree. The number of total nodes counting internal
* nodes is ((2 * alphabet_size) - 1). zero_freq_count is the number
* of elements remaining which have zero frequency. zero_freq_exp and
* zero_freq_rem satisfy the equation zero_freq_count =
* 2^zero_freq_exp + zero_freq_rem. root_node is the root of the
* tree, which is initialized to a node with zero frequency and
* contains the 0th such element. free_node contains a pointer to the
* next available fgk_node space. alphabet contains all the elements
* and is indexed by N. remaining_zeros points to the head of the
* list of zeros. */
struct _fgk_stream
{
usize_t alphabet_size;
usize_t zero_freq_count;
usize_t zero_freq_exp;
usize_t zero_freq_rem;
usize_t coded_depth;
usize_t total_nodes;
usize_t total_blocks;
fgk_bit *coded_bits;
fgk_block *block_array;
fgk_block *free_block;
fgk_node *decode_ptr;
fgk_node *remaining_zeros;
fgk_node *alphabet;
fgk_node *root_node;
fgk_node *free_node;
};
/*********************************************************************/
/* Encoder */
/*********************************************************************/
static fgk_stream* fgk_alloc (xd3_stream *stream /*, usize_t alphabet_size */);
static int fgk_init (xd3_stream *stream,
fgk_stream *h,
int is_encode);
static int fgk_encode_data (fgk_stream *h,
usize_t n);
static inline fgk_bit fgk_get_encoded_bit (fgk_stream *h);
static int xd3_encode_fgk (xd3_stream *stream,
fgk_stream *sec_stream,
xd3_output *input,
xd3_output *output,
xd3_sec_cfg *cfg);
/*********************************************************************/
/* Decoder */
/*********************************************************************/
static inline int fgk_decode_bit (fgk_stream *h,
fgk_bit b);
static int fgk_decode_data (fgk_stream *h);
static void fgk_destroy (xd3_stream *stream,
fgk_stream *h);
static int xd3_decode_fgk (xd3_stream *stream,
fgk_stream *sec_stream,
const uint8_t **input,
const uint8_t *const input_end,
uint8_t **output,
const uint8_t *const output_end);
/*********************************************************************/
/* Private */
/*********************************************************************/
static unsigned int fgk_find_nth_zero (fgk_stream *h, usize_t n);
static usize_t fgk_nth_zero (fgk_stream *h, usize_t n);
static void fgk_update_tree (fgk_stream *h, usize_t n);
static fgk_node* fgk_increase_zero_weight (fgk_stream *h, usize_t n);
static void fgk_eliminate_zero (fgk_stream* h, fgk_node *node);
static void fgk_move_right (fgk_stream *h, fgk_node *node);
static void fgk_promote (fgk_stream *h, fgk_node *node);
static void fgk_init_node (fgk_node *node, usize_t i, usize_t size);
static fgk_block* fgk_make_block (fgk_stream *h, fgk_node *l);
static void fgk_free_block (fgk_stream *h, fgk_block *b);
static void fgk_factor_remaining (fgk_stream *h);
static inline void fgk_swap_ptrs (fgk_node **one, fgk_node **two);
/*********************************************************************/
/* Basic Routines */
/*********************************************************************/
/* returns an initialized huffman encoder for an alphabet with the
* given size. returns NULL if enough memory cannot be allocated */
static fgk_stream* fgk_alloc (xd3_stream *stream /*, int alphabet_size0 */)
{
usize_t alphabet_size0 = ALPHABET_SIZE;
fgk_stream *h;
if ((h = (fgk_stream*) xd3_alloc (stream, 1, sizeof (fgk_stream))) == NULL)
{
return NULL;
}
h->total_nodes = (2 * alphabet_size0) - 1;
h->total_blocks = (2 * h->total_nodes);
h->alphabet = (fgk_node*) xd3_alloc (stream, h->total_nodes, sizeof (fgk_node));
h->block_array = (fgk_block*) xd3_alloc (stream, h->total_blocks, sizeof (fgk_block));
h->coded_bits = (fgk_bit*) xd3_alloc (stream, alphabet_size0, sizeof (fgk_bit));
if (h->coded_bits == NULL ||
h->alphabet == NULL ||
h->block_array == NULL)
{
fgk_destroy (stream, h);
return NULL;
}
h->alphabet_size = alphabet_size0;
return h;
}
static int fgk_init (xd3_stream *stream, fgk_stream *h, int is_encode)
{
usize_t ui;
ssize_t si;
h->root_node = h->alphabet;
h->decode_ptr = h->root_node;
h->free_node = h->alphabet + h->alphabet_size;
h->remaining_zeros = h->alphabet;
h->coded_depth = 0;
h->zero_freq_count = h->alphabet_size + 2;
/* after two calls to factor_remaining, zero_freq_count == alphabet_size */
fgk_factor_remaining(h); /* set ZFE and ZFR */
fgk_factor_remaining(h); /* set ZFDB according to prev state */
IF_DEBUG (memset (h->alphabet, 0, sizeof (h->alphabet[0]) * h->total_nodes));
for (ui = 0; ui < h->total_blocks-1; ui += 1)
{
h->block_array[ui].block_freeptr = &h->block_array[ui + 1];
}
h->block_array[h->total_blocks - 1].block_freeptr = NULL;
h->free_block = h->block_array;
/* Zero frequency nodes are inserted in the first alphabet_size
* positions, with Value, weight, and a pointer to the next zero
* frequency node. */
for (si = h->alphabet_size - 1; si >= 0; si -= 1)
{
fgk_init_node (h->alphabet + si, (usize_t) si, h->alphabet_size);
}
return 0;
}
static void fgk_swap_ptrs(fgk_node **one, fgk_node **two)
{
fgk_node *tmp = *one;
*one = *two;
*two = tmp;
}
/* Takes huffman transmitter h and n, the nth elt in the alphabet, and
* returns the number of required to encode n. */
static int fgk_encode_data (fgk_stream* h, usize_t n)
{
fgk_node *target_ptr = h->alphabet + n;
XD3_ASSERT (n < h->alphabet_size);
h->coded_depth = 0;
/* First encode the binary representation of the nth remaining
* zero frequency element in reverse such that bit, which will be
* encoded from h->coded_depth down to 0 will arrive in increasing
* order following the tree path. If there is only one left, it
* is not neccesary to encode these bits. */
if (IS_ADAPTIVE && target_ptr->weight == 0)
{
unsigned int where, shift;
int bits;
where = fgk_find_nth_zero(h, n);
shift = 1;
if (h->zero_freq_rem == 0)
{
bits = h->zero_freq_exp;
}
else
{
bits = h->zero_freq_exp + 1;
}
while (bits > 0)
{
h->coded_bits[h->coded_depth++] = (shift & where) && 1;
bits -= 1;
shift <<= 1;
};
target_ptr = h->remaining_zeros;
}
/* The path from root to node is filled into coded_bits in reverse so
* that it is encoded in the right order */
while (target_ptr != h->root_node)
{
h->coded_bits[h->coded_depth++] = (target_ptr->parent->right_child == target_ptr);
target_ptr = target_ptr->parent;
}
if (IS_ADAPTIVE)
{
fgk_update_tree(h, n);
}
return h->coded_depth;
}
/* Should be called as many times as fgk_encode_data returns.
*/
static inline fgk_bit fgk_get_encoded_bit (fgk_stream *h)
{
XD3_ASSERT (h->coded_depth > 0);
return h->coded_bits[--h->coded_depth];
}
/* This procedure updates the tree after alphabet[n] has been encoded
* or decoded.
*/
static void fgk_update_tree (fgk_stream *h, usize_t n)
{
fgk_node *incr_node;
if (h->alphabet[n].weight == 0)
{
incr_node = fgk_increase_zero_weight (h, n);
}
else
{
incr_node = h->alphabet + n;
}
while (incr_node != h->root_node)
{
fgk_move_right (h, incr_node);
fgk_promote (h, incr_node);
incr_node->weight += 1; /* incr the parent */
incr_node = incr_node->parent; /* repeat */
}
h->root_node->weight += 1;
}
static void fgk_move_right (fgk_stream *h, fgk_node *move_fwd)
{
fgk_node **fwd_par_ptr, **back_par_ptr;
fgk_node *move_back, *tmp;
move_back = move_fwd->my_block->block_leader;
if (move_fwd == move_back ||
move_fwd->parent == move_back ||
move_fwd->weight == 0)
{
return;
}
move_back->right->left = move_fwd;
if (move_fwd->left)
{
move_fwd->left->right = move_back;
}
tmp = move_fwd->right;
move_fwd->right = move_back->right;
if (tmp == move_back)
{
move_back->right = move_fwd;
}
else
{
tmp->left = move_back;
move_back->right = tmp;
}
tmp = move_back->left;
move_back->left = move_fwd->left;
if (tmp == move_fwd)
{
move_fwd->left = move_back;
}
else
{
tmp->right = move_fwd;
move_fwd->left = tmp;
}
if (move_fwd->parent->right_child == move_fwd)
{
fwd_par_ptr = &move_fwd->parent->right_child;
}
else
{
fwd_par_ptr = &move_fwd->parent->left_child;
}
if (move_back->parent->right_child == move_back)
{
back_par_ptr = &move_back->parent->right_child;
}
else
{
back_par_ptr = &move_back->parent->left_child;
}
fgk_swap_ptrs (&move_fwd->parent, &move_back->parent);
fgk_swap_ptrs (fwd_par_ptr, back_par_ptr);
move_fwd->my_block->block_leader = move_fwd;
}
/* Shifts node, the leader of its block, into the next block. */
static void fgk_promote (fgk_stream *h, fgk_node *node)
{
fgk_node *my_left, *my_right;
fgk_block *cur_block;
my_right = node->right;
my_left = node->left;
cur_block = node->my_block;
if (node->weight == 0)
{
return;
}
/* if left is right child, parent of remaining zeros case (?), means parent
* has same weight as right child. */
if (my_left == node->right_child &&
node->left_child &&
node->left_child->weight == 0)
{
XD3_ASSERT (node->left_child == h->remaining_zeros);
XD3_ASSERT (node->right_child->weight == (node->weight+1)); /* child weight was already incremented */
if (node->weight == (my_right->weight - 1) && my_right != h->root_node)
{
fgk_free_block (h, cur_block);
node->my_block = my_right->my_block;
my_left->my_block = my_right->my_block;
}
return;
}
if (my_left == h->remaining_zeros)
{
return;
}
/* true if not the leftmost node */
if (my_left->my_block == cur_block)
{
my_left->my_block->block_leader = my_left;
}
else
{
fgk_free_block (h, cur_block);
}
/* node->parent != my_right */
if ((node->weight == (my_right->weight - 1)) && (my_right != h->root_node))
{
node->my_block = my_right->my_block;
}
else
{
node->my_block = fgk_make_block (h, node);
}
}
/* When an element is seen the first time this is called to remove it from the list of
* zero weight elements and introduce a new internal node to the tree. */
static fgk_node* fgk_increase_zero_weight (fgk_stream *h, usize_t n)
{
fgk_node *this_zero, *new_internal, *zero_ptr;
this_zero = h->alphabet + n;
if (h->zero_freq_count == 1)
{
/* this is the last one */
this_zero->right_child = NULL;
if (this_zero->right->weight == 1)
{
this_zero->my_block = this_zero->right->my_block;
}
else
{
this_zero->my_block = fgk_make_block (h, this_zero);
}
h->remaining_zeros = NULL;
return this_zero;
}
zero_ptr = h->remaining_zeros;
new_internal = h->free_node++;
new_internal->parent = zero_ptr->parent;
new_internal->right = zero_ptr->right;
new_internal->weight = 0;
new_internal->right_child = this_zero;
new_internal->left = this_zero;
if (h->remaining_zeros == h->root_node)
{
/* This is the first element to be coded */
h->root_node = new_internal;
this_zero->my_block = fgk_make_block (h, this_zero);
new_internal->my_block = fgk_make_block (h, new_internal);
}
else
{
new_internal->right->left = new_internal;
if (zero_ptr->parent->right_child == zero_ptr)
{
zero_ptr->parent->right_child = new_internal;
}
else
{
zero_ptr->parent->left_child = new_internal;
}
if (new_internal->right->weight == 1)
{
new_internal->my_block = new_internal->right->my_block;
}
else
{
new_internal->my_block = fgk_make_block (h, new_internal);
}
this_zero->my_block = new_internal->my_block;
}
fgk_eliminate_zero (h, this_zero);
new_internal->left_child = h->remaining_zeros;
this_zero->right = new_internal;
this_zero->left = h->remaining_zeros;
this_zero->parent = new_internal;
this_zero->left_child = NULL;
this_zero->right_child = NULL;
h->remaining_zeros->parent = new_internal;
h->remaining_zeros->right = this_zero;
return this_zero;
}
/* When a zero frequency element is encoded, it is followed by the
* binary representation of the index into the remaining elements.
* Sets a cache to the element before it so that it can be removed
* without calling this procedure again. */
static unsigned int fgk_find_nth_zero (fgk_stream* h, usize_t n)
{
fgk_node *target_ptr = h->alphabet + n;
fgk_node *head_ptr = h->remaining_zeros;
unsigned int idx = 0;
while (target_ptr != head_ptr)
{
head_ptr = head_ptr->right_child;
idx += 1;
}
return idx;
}
/* Splices node out of the list of zeros. */
static void fgk_eliminate_zero (fgk_stream* h, fgk_node *node)
{
if (h->zero_freq_count == 1)
{
return;
}
fgk_factor_remaining(h);
if (node->left_child == NULL)
{
h->remaining_zeros = h->remaining_zeros->right_child;
h->remaining_zeros->left_child = NULL;
}
else if (node->right_child == NULL)
{
node->left_child->right_child = NULL;
}
else
{
node->right_child->left_child = node->left_child;
node->left_child->right_child = node->right_child;
}
}
static void fgk_init_node (fgk_node *node, usize_t i, usize_t size)
{
if (i < size - 1)
{
node->right_child = node + 1;
}
else
{
node->right_child = NULL;
}
if (i >= 1)
{
node->left_child = node - 1;
}
else
{
node->left_child = NULL;
}
node->weight = 0;
node->parent = NULL;
node->right = NULL;
node->left = NULL;
node->my_block = NULL;
}
/* The data structure used is an array of blocks, which are unions of
* free pointers and huffnode pointers. free blocks are a linked list
* of free blocks, the front of which is h->free_block. The used
* blocks are pointers to the head of each block. */
static fgk_block* fgk_make_block (fgk_stream *h, fgk_node* lead)
{
fgk_block *ret = h->free_block;
XD3_ASSERT (h->free_block != NULL);
h->free_block = h->free_block->block_freeptr;
ret->block_leader = lead;
return ret;
}
/* Restores the block to the front of the free list. */
static void fgk_free_block (fgk_stream *h, fgk_block *b)
{
b->block_freeptr = h->free_block;
h->free_block = b;
}
/* sets zero_freq_count, zero_freq_rem, and zero_freq_exp to satsity
* the equation given above. */
static void fgk_factor_remaining (fgk_stream *h)
{
unsigned int i;
i = (--h->zero_freq_count);
h->zero_freq_exp = 0;
while (i > 1)
{
h->zero_freq_exp += 1;
i >>= 1;
}
i = 1 << h->zero_freq_exp;
h->zero_freq_rem = h->zero_freq_count - i;
}
/* receives a bit at a time and returns true when a complete code has
* been received.
*/
static inline int fgk_decode_bit (fgk_stream* h, fgk_bit b)
{
XD3_ASSERT (b == 1 || b == 0);
if (IS_ADAPTIVE && h->decode_ptr->weight == 0)
{
usize_t bitsreq;
if (h->zero_freq_rem == 0)
{
bitsreq = h->zero_freq_exp;
}
else
{
bitsreq = h->zero_freq_exp + 1;
}
h->coded_bits[h->coded_depth] = b;
h->coded_depth += 1;
return h->coded_depth >= bitsreq;
}
else
{
if (b)
{
h->decode_ptr = h->decode_ptr->right_child;
}
else
{
h->decode_ptr = h->decode_ptr->left_child;
}
if (h->decode_ptr->left_child == NULL)
{
/* If the weight is non-zero, finished. */
if (h->decode_ptr->weight != 0)
{
return 1;
}
/* zero_freq_count is dropping to 0, finished. */
return h->zero_freq_count == 1;
}
else
{
return 0;
}
}
}
static usize_t fgk_nth_zero (fgk_stream* h, usize_t n)
{
fgk_node *ret = h->remaining_zeros;
/* ERROR: if during this loop (ret->right_child == NULL) then the
* encoder's zero count is too high. Could return an error code
* now, but is probably unnecessary overhead, since the caller
* should check integrity anyway. */
for (; n != 0 && ret->right_child != NULL; n -= 1)
{
ret = ret->right_child;
}
return (usize_t)(ret - h->alphabet);
}
/* once fgk_decode_bit returns 1, this retrieves an index into the
* alphabet otherwise this returns 0, indicating more bits are
* required.
*/
static int fgk_decode_data (fgk_stream* h)
{
usize_t elt = (usize_t)(h->decode_ptr - h->alphabet);
if (IS_ADAPTIVE && h->decode_ptr->weight == 0) {
usize_t i = 0;
usize_t n = 0;
if (h->coded_depth > 0)
{
for (; i < h->coded_depth - 1; i += 1)
{
n |= h->coded_bits[i];
n <<= 1;
}
}
n |= h->coded_bits[i];
elt = fgk_nth_zero(h, n);
}
h->coded_depth = 0;
if (IS_ADAPTIVE)
{
fgk_update_tree(h, elt);
}
h->decode_ptr = h->root_node;
return elt;
}
static void fgk_destroy (xd3_stream *stream,
fgk_stream *h)
{
if (h != NULL)
{
xd3_free (stream, h->alphabet);
xd3_free (stream, h->coded_bits);
xd3_free (stream, h->block_array);
xd3_free (stream, h);
}
}
/*********************************************************************/
/* Xdelta */
/*********************************************************************/
static int
xd3_encode_fgk (xd3_stream *stream, fgk_stream *sec_stream, xd3_output *input, xd3_output *output, xd3_sec_cfg *cfg)
{
bit_state bstate = BIT_STATE_ENCODE_INIT;
xd3_output *cur_page;
int ret;
/* OPT: quit compression early if it looks bad */
for (cur_page = input; cur_page; cur_page = cur_page->next_page)
{
const uint8_t *inp = cur_page->base;
const uint8_t *inp_max = inp + cur_page->next;
while (inp < inp_max)
{
usize_t bits = fgk_encode_data (sec_stream, *inp++);
while (bits--)
{
if ((ret = xd3_encode_bit (stream, & output, & bstate, fgk_get_encoded_bit (sec_stream)))) { return ret; }
}
}
}
return xd3_flush_bits (stream, & output, & bstate);
}
static int
xd3_decode_fgk (xd3_stream *stream,
fgk_stream *sec_stream,
const uint8_t **input_pos,
const uint8_t *const input_max,
uint8_t **output_pos,
const uint8_t *const output_max)
{
bit_state bstate;
uint8_t *output = *output_pos;
const uint8_t *input = *input_pos;
for (;;)
{
if (input == input_max)
{
stream->msg = "secondary decoder end of input";
return XD3_INTERNAL;
}
bstate.cur_byte = *input++;
for (bstate.cur_mask = 1; bstate.cur_mask != 0x100; bstate.cur_mask <<= 1)
{
int done = fgk_decode_bit (sec_stream, (bstate.cur_byte & bstate.cur_mask) ? 1U : 0U);
if (! done) { continue; }
*output++ = fgk_decode_data (sec_stream);
if (output == output_max)
{
/* During regression testing: */
IF_REGRESSION ({
int ret;
bstate.cur_mask <<= 1;
if ((ret = xd3_test_clean_bits (stream, & bstate))) { return ret; }
});
(*output_pos) = output;
(*input_pos) = input;
return 0;
}
}
}
}
#endif /* _XDELTA3_FGK_ */

170
3rdparty/xdelta3-3.0.8/xdelta3-hash.h vendored Normal file
View File

@@ -0,0 +1,170 @@
/* xdelta 3 - delta compression tools and library
* Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007. Joshua P. MacDonald
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _XDELTA3_HASH_H_
#define _XDELTA3_HASH_H_
#if XD3_DEBUG
#define SMALL_HASH_DEBUG1(s,inp) \
uint32_t debug_state; \
uint32_t debug_hval = xd3_checksum_hash (& (s)->small_hash, \
xd3_scksum (&debug_state, (inp), (s)->smatcher.small_look))
#define SMALL_HASH_DEBUG2(s,inp) \
XD3_ASSERT (debug_hval == xd3_checksum_hash (& (s)->small_hash, \
xd3_scksum (&debug_state, (inp), (s)->smatcher.small_look)))
#else
#define SMALL_HASH_DEBUG1(s,inp)
#define SMALL_HASH_DEBUG2(s,inp)
#endif /* XD3_DEBUG */
/* This is a good hash multiplier for 32-bit LCGs: see "linear
* congruential generators of different sizes and good lattice
* structure" */
static const uint32_t hash_multiplier = 1597334677U;
/***********************************************************************
Permute stuff
***********************************************************************/
#if HASH_PERMUTE == 0
#define PERMUTE(x) (x)
#else
#define PERMUTE(x) (__single_hash[(uint32_t)x])
extern const uint16_t __single_hash[256];
#endif
/* Update the checksum state. */
#if ADLER_LARGE_CKSUM
inline uint32_t
xd3_large_cksum_update (uint32_t cksum,
const uint8_t *base,
usize_t look) {
uint32_t old_c = PERMUTE(base[0]);
uint32_t new_c = PERMUTE(base[look]);
uint32_t low = ((cksum & 0xffff) - old_c + new_c) & 0xffff;
uint32_t high = ((cksum >> 16) - (old_c * look) + low) & 0xffff;
return (high << 16) | low;
}
#else
/* TODO: revisit this topic */
#endif
#if UNALIGNED_OK
#define UNALIGNED_READ32(dest,src) (*(dest)) = (*(uint32_t*)(src))
#else
#define UNALIGNED_READ32(dest,src) memcpy((dest), (src), 4);
#endif
/* TODO: small cksum is hard-coded for 4 bytes (i.e., "look" is unused) */
static inline uint32_t
xd3_scksum (uint32_t *state,
const uint8_t *base,
const usize_t look)
{
UNALIGNED_READ32(state, base);
return (*state) * hash_multiplier;
}
static inline uint32_t
xd3_small_cksum_update (uint32_t *state,
const uint8_t *base,
usize_t look)
{
UNALIGNED_READ32(state, base+1);
return (*state) * hash_multiplier;
}
/***********************************************************************
Ctable stuff
***********************************************************************/
static inline usize_t
xd3_checksum_hash (const xd3_hash_cfg *cfg, const usize_t cksum)
{
return (cksum >> cfg->shift) ^ (cksum & cfg->mask);
}
/***********************************************************************
Cksum function
***********************************************************************/
#if ADLER_LARGE_CKSUM
static inline uint32_t
xd3_lcksum (const uint8_t *seg, const usize_t ln)
{
usize_t i = 0;
uint32_t low = 0;
uint32_t high = 0;
for (; i < ln; i += 1)
{
low += PERMUTE(*seg++);
high += low;
}
return ((high & 0xffff) << 16) | (low & 0xffff);
}
#else
static inline uint32_t
xd3_lcksum (const uint8_t *seg, const usize_t ln)
{
usize_t i, j;
uint32_t h = 0;
for (i = 0, j = ln - 1; i < ln; ++i, --j) {
h += PERMUTE(seg[i]) * hash_multiplier_powers[j];
}
return h;
}
#endif
#if XD3_ENCODER
static usize_t
xd3_size_log2 (usize_t slots)
{
int bits = 28; /* This should not be an unreasonable limit. */
int i;
for (i = 3; i <= bits; i += 1)
{
if (slots < (1U << i))
{
/* TODO: this is compaction=1 in checksum_test.cc and maybe should
* not be fixed at -1. */
bits = i - 1;
break;
}
}
return bits;
}
static void
xd3_size_hashtable (xd3_stream *stream,
usize_t slots,
xd3_hash_cfg *cfg)
{
int bits = xd3_size_log2 (slots);
/* TODO: there's a 32-bit assumption here */
cfg->size = (1 << bits);
cfg->mask = (cfg->size - 1);
cfg->shift = 32 - bits;
}
#endif
#endif

View File

@@ -0,0 +1,145 @@
/* xdelta3 - delta compression tools and library
* Copyright (C) 2011, 2012 Joshua P. MacDonald
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef XDELTA3_INTERNAL_H__
#define XDELTA3_INTERNAL_H__
#include "xdelta3.h"
typedef struct _main_file main_file;
typedef struct _main_extcomp main_extcomp;
void main_buffree (void *ptr);
void* main_bufalloc (size_t size);
void main_file_init (main_file *xfile);
int main_file_close (main_file *xfile);
void main_file_cleanup (main_file *xfile);
int main_file_isopen (main_file *xfile);
int main_file_open (main_file *xfile, const char* name, int mode);
int main_file_exists (main_file *xfile);
int xd3_whole_append_window (xd3_stream *stream);
int xd3_main_cmdline (int argc, char **argv);
int main_file_read (main_file *ifile,
uint8_t *buf,
size_t size,
size_t *nread,
const char *msg);
int main_file_write (main_file *ofile, uint8_t *buf,
usize_t size, const char *msg);
int test_compare_files (const char* f0, const char* f1);
usize_t xd3_bytes_on_srcblk (xd3_source *src, xoff_t blkno);
xoff_t xd3_source_eof(const xd3_source *src);
uint32_t xd3_large_cksum_update (uint32_t cksum,
const uint8_t *base,
usize_t look);
int xd3_encode_init_full (xd3_stream *stream);
#if PYTHON_MODULE || SWIG_MODULE || NOT_MAIN
int xd3_main_cmdline (int argc, char **argv);
#endif
/* main_file->mode values */
typedef enum
{
XO_READ = 0,
XO_WRITE = 1
} main_file_modes;
struct _main_file
{
#if XD3_STDIO
FILE *file;
#elif XD3_POSIX
int file;
#elif XD3_WIN32
HANDLE file;
#endif
int mode; /* XO_READ and XO_WRITE */
const char *filename; /* File name or /dev/stdin,
* /dev/stdout, /dev/stderr. */
char *filename_copy; /* File name or /dev/stdin,
* /dev/stdout, /dev/stderr. */
const char *realname; /* File name or /dev/stdin,
* /dev/stdout, /dev/stderr. */
const main_extcomp *compressor; /* External compression struct. */
int flags; /* RD_FIRST, RD_NONEXTERNAL, ... */
xoff_t nread; /* for input position */
xoff_t nwrite; /* for output position */
uint8_t *snprintf_buf; /* internal snprintf() use */
int size_known; /* Set by main_set_souze */
xoff_t source_position; /* for avoiding seek in getblk_func */
int seek_failed; /* after seek fails once, try FIFO */
};
/* According to the internet, Windows vsnprintf() differs from most
* Unix implementations regarding the terminating 0 when the boundary
* condition is met. It doesn't matter here, we don't rely on the
* trailing 0. Besides, both Windows and DJGPP vsnprintf return -1
* upon truncation, which isn't C99 compliant. To overcome this,
* recent MinGW runtimes provided their own vsnprintf (notice the
* absence of the '_' prefix) but they were initially buggy. So,
* always use the native '_'-prefixed version with Win32. */
#ifdef _WIN32
#define vsnprintf_func(str,size,fmt,args) \
_vsnprintf_s(str,size,size-1,fmt,args)
#define snprintf_func(str,size,fmt,...) \
_snprintf_s(str,size,size-1,fmt,__VA_ARGS__)
#else
#define vsnprintf_func vsnprintf
#define snprintf_func snprintf
#endif
#define short_sprintf(sb,fmt,...) \
snprintf_func((sb).buf,sizeof((sb).buf),fmt,__VA_ARGS__)
/* Type used for short snprintf calls. */
typedef struct {
char buf[48];
} shortbuf;
/* Prior to SVN 303 this function was only defined in DJGPP and WIN32
* environments and other platforms would use the builtin snprintf()
* with an arrangement of macros below. In OS X 10.6, Apply made
* snprintf() a macro, which defeated those macros (since snprintf
* would be evaluated before its argument macros were expanded,
* therefore always define xsnprintf_func. */
#undef PRINTF_ATTRIBUTE
#ifdef __GNUC__
/* Let's just assume no one uses gcc 2.x! */
#define PRINTF_ATTRIBUTE(x,y) __attribute__ ((__format__ (__printf__, x, y)))
#else
#define PRINTF_ATTRIBUTE(x,y)
#endif
/* Underlying xprintf() */
int xsnprintf_func (char *str, int n, const char *fmt, ...)
PRINTF_ATTRIBUTE(3,4);
/* XPR(NT "", ...) (used by main) prefixes an "xdelta3: " to the output. */
void xprintf(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
#define XPR xprintf
#define NT "xdelta3: "
#define NTR ""
#ifndef UINT32_MAX
#define UINT32_MAX 4294967295U
#endif
#ifndef UINT64_MAX
#define UINT64_MAX 18446744073709551615ULL
#endif
#endif // XDELTA3_INTERNAL_H__

130
3rdparty/xdelta3-3.0.8/xdelta3-list.h vendored Normal file
View File

@@ -0,0 +1,130 @@
/* xdelta 3 - delta compression tools and library
* Copyright (C) 2002, 2006, 2007. Joshua P. MacDonald
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __XDELTA3_LIST__
#define __XDELTA3_LIST__
#define XD3_MAKELIST(LTYPE,ETYPE,LNAME) \
\
static inline ETYPE* \
LTYPE ## _entry (LTYPE* l) \
{ \
return (ETYPE*) ((char*) l - (ptrdiff_t) &((ETYPE*) 0)->LNAME); \
} \
\
static inline void \
LTYPE ## _init (LTYPE *l) \
{ \
l->next = l; \
l->prev = l; \
} \
\
static inline void \
LTYPE ## _add (LTYPE *prev, LTYPE *next, LTYPE *ins) \
{ \
next->prev = ins; \
prev->next = ins; \
ins->next = next; \
ins->prev = prev; \
} \
\
static inline void \
LTYPE ## _push_back (LTYPE *l, ETYPE *i) \
{ \
LTYPE ## _add (l->prev, l, & i->LNAME); \
} \
\
static inline void \
LTYPE ## _del (LTYPE *next, \
LTYPE *prev) \
{ \
next->prev = prev; \
prev->next = next; \
} \
\
static inline ETYPE* \
LTYPE ## _remove (ETYPE *f) \
{ \
LTYPE *i = f->LNAME.next; \
LTYPE ## _del (f->LNAME.next, f->LNAME.prev); \
return LTYPE ## _entry (i); \
} \
\
static inline ETYPE* \
LTYPE ## _pop_back (LTYPE *l) \
{ \
LTYPE *i = l->prev; \
LTYPE ## _del (i->next, i->prev); \
return LTYPE ## _entry (i); \
} \
\
static inline ETYPE* \
LTYPE ## _pop_front (LTYPE *l) \
{ \
LTYPE *i = l->next; \
LTYPE ## _del (i->next, i->prev); \
return LTYPE ## _entry (i); \
} \
\
static inline int \
LTYPE ## _empty (LTYPE *l) \
{ \
return l == l->next; \
} \
\
static inline ETYPE* \
LTYPE ## _front (LTYPE *f) \
{ \
return LTYPE ## _entry (f->next); \
} \
\
static inline ETYPE* \
LTYPE ## _back (LTYPE *f) \
{ \
return LTYPE ## _entry (f->prev); \
} \
\
static inline int \
LTYPE ## _end (LTYPE *f, ETYPE *i) \
{ \
return f == & i->LNAME; \
} \
\
static inline ETYPE* \
LTYPE ## _next (ETYPE *f) \
{ \
return LTYPE ## _entry (f->LNAME.next); \
} \
\
static inline usize_t \
LTYPE ## _length (LTYPE *l) \
{ \
LTYPE *p; \
int c = 0; \
\
for (p = l->next; p != l; p = p->next) \
{ \
c += 1; \
} \
\
return c; \
} \
\
typedef int unused_ ## LTYPE
#endif

196
3rdparty/xdelta3-3.0.8/xdelta3-lzma.h vendored Normal file
View File

@@ -0,0 +1,196 @@
/* xdelta 3 - delta compression tools and library
* Copyright (C) 2012, 2013. Joshua P. MacDonald
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Note: The use of the _easy_ decoder means we're not calling the
* xd3_stream malloc hooks. TODO(jmacd) Fix if anyone cares. */
#ifndef _XDELTA3_LZMA_H_
#define _XDELTA3_LZMA_H_
#include <lzma.h>
typedef struct _xd3_lzma_stream xd3_lzma_stream;
struct _xd3_lzma_stream {
lzma_stream lzma;
lzma_options_lzma options;
lzma_filter filters[2];
};
xd3_sec_stream*
xd3_lzma_alloc (xd3_stream *stream)
{
return (xd3_sec_stream*) xd3_alloc (stream, sizeof (xd3_lzma_stream), 1);
}
void
xd3_lzma_destroy (xd3_stream *stream, xd3_sec_stream *sec_stream)
{
xd3_lzma_stream *ls = (xd3_lzma_stream*) sec_stream;
lzma_end (&ls->lzma);
xd3_free (stream, ls);
}
int
xd3_lzma_init (xd3_stream *stream, xd3_lzma_stream *sec, int is_encode)
{
int ret;
memset (&sec->lzma, 0, sizeof(sec->lzma));
if (is_encode)
{
int preset = (stream->flags & XD3_COMPLEVEL_MASK) >> XD3_COMPLEVEL_SHIFT;
if (lzma_lzma_preset(&sec->options, preset))
{
stream->msg = "invalid lzma preset";
return XD3_INVALID;
}
sec->filters[0].id = LZMA_FILTER_LZMA2;
sec->filters[0].options = &sec->options;
sec->filters[1].id = LZMA_VLI_UNKNOWN;
ret = lzma_stream_encoder (&sec->lzma, &sec->filters[0], LZMA_CHECK_NONE);
}
else
{
ret = lzma_stream_decoder (&sec->lzma, UINT64_MAX, LZMA_TELL_NO_CHECK);
}
if (ret != LZMA_OK)
{
stream->msg = "lzma stream init failed";
return XD3_INTERNAL;
}
return 0;
}
int xd3_decode_lzma (xd3_stream *stream, xd3_lzma_stream *sec,
const uint8_t **input_pos,
const uint8_t *const input_end,
uint8_t **output_pos,
const uint8_t *const output_end)
{
uint8_t *output = *output_pos;
const uint8_t *input = *input_pos;
size_t avail_in = input_end - input;
size_t avail_out = output_end - output;
sec->lzma.avail_in = avail_in;
sec->lzma.next_in = input;
sec->lzma.avail_out = avail_out;
sec->lzma.next_out = output;
while (1)
{
int lret = lzma_code (&sec->lzma, LZMA_RUN);
switch (lret)
{
case LZMA_NO_CHECK:
case LZMA_OK:
if (sec->lzma.avail_out == 0)
{
(*output_pos) = sec->lzma.next_out;
(*input_pos) = sec->lzma.next_in;
return 0;
}
break;
default:
stream->msg = "lzma decoding error";
return XD3_INTERNAL;
}
}
}
#if XD3_ENCODER
int xd3_encode_lzma (xd3_stream *stream,
xd3_lzma_stream *sec,
xd3_output *input,
xd3_output *output,
xd3_sec_cfg *cfg)
{
lzma_action action = LZMA_RUN;
cfg->inefficient = 1; /* Can't skip windows */
sec->lzma.next_in = NULL;
sec->lzma.avail_in = 0;
sec->lzma.next_out = (output->base + output->next);
sec->lzma.avail_out = (output->avail - output->next);
while (1)
{
int lret;
size_t nwrite;
if (sec->lzma.avail_in == 0 && input != NULL)
{
sec->lzma.avail_in = input->next;
sec->lzma.next_in = input->base;
if ((input = input->next_page) == NULL)
{
action = LZMA_SYNC_FLUSH;
}
}
lret = lzma_code (&sec->lzma, action);
nwrite = (output->avail - output->next) - sec->lzma.avail_out;
if (nwrite != 0)
{
output->next += nwrite;
if (output->next == output->avail)
{
if ((output = xd3_alloc_output (stream, output)) == NULL)
{
return ENOMEM;
}
sec->lzma.next_out = output->base;
sec->lzma.avail_out = output->avail;
}
}
switch (lret)
{
case LZMA_OK:
break;
case LZMA_STREAM_END:
return 0;
default:
stream->msg = "lzma encoding error";
return XD3_INTERNAL;
}
}
return 0;
}
#endif /* XD3_ENCODER */
#endif /* _XDELTA3_LZMA_H_ */

4048
3rdparty/xdelta3-3.0.8/xdelta3-main.h vendored Normal file

File diff suppressed because it is too large Load Diff

579
3rdparty/xdelta3-3.0.8/xdelta3-merge.h vendored Normal file
View File

@@ -0,0 +1,579 @@
/* xdelta 3 - delta compression tools and library
* Copyright (C) 2007. Joshua P. MacDonald
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _XDELTA3_MERGE_H_
#define _XDELTA3_MERGE_H_
int xd3_merge_inputs (xd3_stream *stream,
xd3_whole_state *source,
xd3_whole_state *input);
static int
xd3_whole_state_init (xd3_stream *stream)
{
XD3_ASSERT (stream->whole_target.adds == NULL);
XD3_ASSERT (stream->whole_target.inst == NULL);
XD3_ASSERT (stream->whole_target.wininfo == NULL);
XD3_ASSERT (stream->whole_target.length == 0);
stream->whole_target.adds_alloc = XD3_ALLOCSIZE;
stream->whole_target.inst_alloc = XD3_ALLOCSIZE;
stream->whole_target.wininfo_alloc = XD3_ALLOCSIZE;
if ((stream->whole_target.adds = (uint8_t*)
xd3_alloc (stream, stream->whole_target.adds_alloc, 1)) == NULL ||
(stream->whole_target.inst = (xd3_winst*)
xd3_alloc (stream, stream->whole_target.inst_alloc, 1)) == NULL ||
(stream->whole_target.wininfo = (xd3_wininfo*)
xd3_alloc (stream, stream->whole_target.wininfo_alloc, 1)) == NULL)
{
return ENOMEM;
}
return 0;
}
static void
xd3_swap_whole_state (xd3_whole_state *a,
xd3_whole_state *b)
{
xd3_whole_state tmp;
XD3_ASSERT (a->inst != NULL && a->adds != NULL);
XD3_ASSERT (b->inst != NULL && b->adds != NULL);
XD3_ASSERT (b->wininfo != NULL && b->wininfo != NULL);
memcpy (&tmp, a, sizeof (xd3_whole_state));
memcpy (a, b, sizeof (xd3_whole_state));
memcpy (b, &tmp, sizeof (xd3_whole_state));
}
static int
xd3_realloc_buffer (xd3_stream *stream,
usize_t current_units,
usize_t unit_size,
usize_t new_units,
usize_t *alloc_size,
void **alloc_ptr)
{
usize_t needed;
usize_t new_alloc;
usize_t cur_size;
uint8_t *new_buf;
needed = (current_units + new_units) * unit_size;
if (needed <= *alloc_size)
{
return 0;
}
cur_size = current_units * unit_size;
new_alloc = xd3_round_blksize (needed * 2, XD3_ALLOCSIZE);
if ((new_buf = (uint8_t*) xd3_alloc (stream, new_alloc, 1)) == NULL)
{
return ENOMEM;
}
if (cur_size != 0)
{
memcpy (new_buf, *alloc_ptr, cur_size);
}
if (*alloc_ptr != NULL)
{
xd3_free (stream, *alloc_ptr);
}
*alloc_size = new_alloc;
*alloc_ptr = new_buf;
return 0;
}
/* allocate one new output instruction */
static int
xd3_whole_alloc_winst (xd3_stream *stream,
xd3_winst **winstp)
{
int ret;
if ((ret = xd3_realloc_buffer (stream,
stream->whole_target.instlen,
sizeof (xd3_winst),
1,
& stream->whole_target.inst_alloc,
(void**) & stream->whole_target.inst)))
{
return ret;
}
*winstp = &stream->whole_target.inst[stream->whole_target.instlen++];
return 0;
}
static int
xd3_whole_alloc_adds (xd3_stream *stream,
usize_t count)
{
return xd3_realloc_buffer (stream,
stream->whole_target.addslen,
1,
count,
& stream->whole_target.adds_alloc,
(void**) & stream->whole_target.adds);
}
static int
xd3_whole_alloc_wininfo (xd3_stream *stream,
xd3_wininfo **wininfop)
{
int ret;
if ((ret = xd3_realloc_buffer (stream,
stream->whole_target.wininfolen,
sizeof (xd3_wininfo),
1,
& stream->whole_target.wininfo_alloc,
(void**) & stream->whole_target.wininfo)))
{
return ret;
}
*wininfop = &stream->whole_target.wininfo[stream->whole_target.wininfolen++];
return 0;
}
static int
xd3_whole_append_inst (xd3_stream *stream,
xd3_hinst *inst)
{
int ret;
xd3_winst *winst;
if ((ret = xd3_whole_alloc_winst (stream, &winst)))
{
return ret;
}
winst->type = inst->type;
winst->mode = 0;
winst->size = inst->size;
winst->position = stream->whole_target.length;
stream->whole_target.length += inst->size;
if (((inst->type == XD3_ADD) || (inst->type == XD3_RUN)) &&
(ret = xd3_whole_alloc_adds (stream,
(inst->type == XD3_RUN ? 1 : inst->size))))
{
return ret;
}
switch (inst->type)
{
case XD3_RUN:
winst->addr = stream->whole_target.addslen;
stream->whole_target.adds[stream->whole_target.addslen++] =
*stream->data_sect.buf++;
break;
case XD3_ADD:
winst->addr = stream->whole_target.addslen;
memcpy (stream->whole_target.adds + stream->whole_target.addslen,
stream->data_sect.buf,
inst->size);
stream->data_sect.buf += inst->size;
stream->whole_target.addslen += inst->size;
break;
default:
if (inst->addr < stream->dec_cpylen)
{
winst->mode = SRCORTGT (stream->dec_win_ind);
winst->addr = stream->dec_cpyoff + inst->addr;
}
else
{
winst->addr = (stream->dec_winstart +
inst->addr -
stream->dec_cpylen);
}
break;
}
return 0;
}
int
xd3_whole_append_window (xd3_stream *stream)
{
int ret;
xd3_wininfo *wininfo;
if ((ret = xd3_whole_alloc_wininfo (stream, &wininfo))) { return ret; }
wininfo->length = stream->dec_tgtlen;
wininfo->offset = stream->dec_winstart;
wininfo->adler32 = stream->dec_adler32;
while (stream->inst_sect.buf < stream->inst_sect.buf_max)
{
if ((ret = xd3_decode_instruction (stream)))
{
return ret;
}
if ((stream->dec_current1.type != XD3_NOOP) &&
(ret = xd3_whole_append_inst (stream,
& stream->dec_current1)))
{
return ret;
}
if ((stream->dec_current2.type != XD3_NOOP) &&
(ret = xd3_whole_append_inst (stream,
& stream->dec_current2)))
{
return ret;
}
}
return 0;
}
/* xd3_merge_input_output applies *source to *stream, returns the
* result in stream. */
int xd3_merge_input_output (xd3_stream *stream,
xd3_whole_state *source)
{
int ret;
xd3_stream tmp_stream;
memset (& tmp_stream, 0, sizeof (tmp_stream));
if ((ret = xd3_config_stream (& tmp_stream, NULL)) ||
(ret = xd3_whole_state_init (& tmp_stream)) ||
(ret = xd3_merge_inputs (& tmp_stream,
source,
& stream->whole_target)))
{
XPR(NT XD3_LIB_ERRMSG (&tmp_stream, ret));
return ret;
}
/* the output is in tmp_stream.whole_state, swap into input */
xd3_swap_whole_state (& stream->whole_target,
& tmp_stream.whole_target);
/* total allocation counts are preserved */
xd3_free_stream (& tmp_stream);
return 0;
}
static int
xd3_merge_run (xd3_stream *stream,
xd3_whole_state *target,
xd3_winst *iinst)
{
int ret;
xd3_winst *oinst;
if ((ret = xd3_whole_alloc_winst (stream, &oinst)) ||
(ret = xd3_whole_alloc_adds (stream, 1)))
{
return ret;
}
oinst->type = iinst->type;
oinst->mode = iinst->mode;
oinst->size = iinst->size;
oinst->addr = stream->whole_target.addslen;
XD3_ASSERT (stream->whole_target.length == iinst->position);
oinst->position = stream->whole_target.length;
stream->whole_target.length += iinst->size;
stream->whole_target.adds[stream->whole_target.addslen++] =
target->adds[iinst->addr];
return 0;
}
static int
xd3_merge_add (xd3_stream *stream,
xd3_whole_state *target,
xd3_winst *iinst)
{
int ret;
xd3_winst *oinst;
if ((ret = xd3_whole_alloc_winst (stream, &oinst)) ||
(ret = xd3_whole_alloc_adds (stream, iinst->size)))
{
return ret;
}
oinst->type = iinst->type;
oinst->mode = iinst->mode;
oinst->size = iinst->size;
oinst->addr = stream->whole_target.addslen;
XD3_ASSERT (stream->whole_target.length == iinst->position);
oinst->position = stream->whole_target.length;
stream->whole_target.length += iinst->size;
memcpy(stream->whole_target.adds + stream->whole_target.addslen,
target->adds + iinst->addr,
iinst->size);
stream->whole_target.addslen += iinst->size;
return 0;
}
static int
xd3_merge_target_copy (xd3_stream *stream,
xd3_winst *iinst)
{
int ret;
xd3_winst *oinst;
if ((ret = xd3_whole_alloc_winst (stream, &oinst)))
{
return ret;
}
XD3_ASSERT (stream->whole_target.length == iinst->position);
memcpy (oinst, iinst, sizeof (*oinst));
return 0;
}
static int
xd3_merge_find_position (xd3_stream *stream,
xd3_whole_state *source,
xoff_t address,
usize_t *inst_num)
{
usize_t low;
usize_t high;
if (address >= source->length)
{
stream->msg = "Invalid copy offset in merge";
return XD3_INVALID_INPUT;
}
low = 0;
high = source->instlen;
while (low != high)
{
xoff_t mid_lpos;
xoff_t mid_hpos;
usize_t mid = low + (high - low) / 2;
mid_lpos = source->inst[mid].position;
if (address < mid_lpos)
{
high = mid;
continue;
}
mid_hpos = mid_lpos + source->inst[mid].size;
if (address >= mid_hpos)
{
low = mid + 1;
continue;
}
*inst_num = mid;
return 0;
}
stream->msg = "Internal error in merge";
return XD3_INTERNAL;
}
static int
xd3_merge_source_copy (xd3_stream *stream,
xd3_whole_state *source,
const xd3_winst *iinst_orig)
{
int ret;
xd3_winst iinst;
usize_t sinst_num;
memcpy (& iinst, iinst_orig, sizeof (iinst));
XD3_ASSERT (iinst.mode == VCD_SOURCE);
if ((ret = xd3_merge_find_position (stream, source,
iinst.addr, &sinst_num)))
{
return ret;
}
while (iinst.size > 0)
{
xd3_winst *sinst;
xd3_winst *minst;
usize_t sinst_offset;
usize_t sinst_left;
usize_t this_take;
XD3_ASSERT (sinst_num < source->instlen);
sinst = &source->inst[sinst_num];
XD3_ASSERT (iinst.addr >= sinst->position);
sinst_offset = (usize_t)(iinst.addr - sinst->position);
XD3_ASSERT (sinst->size > sinst_offset);
sinst_left = sinst->size - sinst_offset;
this_take = min (iinst.size, sinst_left);
XD3_ASSERT (this_take > 0);
if ((ret = xd3_whole_alloc_winst (stream, &minst)))
{
return ret;
}
minst->size = this_take;
minst->type = sinst->type;
minst->position = iinst.position;
minst->mode = 0;
switch (sinst->type)
{
case XD3_RUN:
if ((ret = xd3_whole_alloc_adds (stream, 1)))
{
return ret;
}
minst->addr = stream->whole_target.addslen;
stream->whole_target.adds[stream->whole_target.addslen++] =
source->adds[sinst->addr];
break;
case XD3_ADD:
if ((ret = xd3_whole_alloc_adds (stream, this_take)))
{
return ret;
}
minst->addr = stream->whole_target.addslen;
memcpy(stream->whole_target.adds + stream->whole_target.addslen,
source->adds + sinst->addr + sinst_offset,
this_take);
stream->whole_target.addslen += this_take;
break;
default:
if (sinst->mode != 0)
{
minst->mode = sinst->mode;
minst->addr = sinst->addr + sinst_offset;
}
else
{
// TODO: this is slow because of the recursion, which
// could reach a depth equal to the number of target
// copies, and this is compression-inefficient because
// it can produce duplicate adds.
xd3_winst tinst;
tinst.type = XD3_CPY;
tinst.mode = iinst.mode;
tinst.addr = sinst->addr + sinst_offset;
tinst.size = this_take;
tinst.position = iinst.position;
// The instruction allocated in this frame will not be used.
stream->whole_target.instlen -= 1;
if ((ret = xd3_merge_source_copy (stream, source, &tinst)))
{
return ret;
}
}
break;
}
iinst.position += this_take;
iinst.addr += this_take;
iinst.size -= this_take;
sinst_num += 1;
}
return 0;
}
/* xd3_merge_inputs() applies *input to *source, returns its result in
* stream. */
int xd3_merge_inputs (xd3_stream *stream,
xd3_whole_state *source,
xd3_whole_state *input)
{
int ret = 0;
usize_t i;
size_t input_i;
for (i = 0; i < input->wininfolen; ++i) {
xd3_wininfo *copyinfo;
if ((ret = xd3_whole_alloc_wininfo (stream, &copyinfo))) { return ret; }
*copyinfo = input->wininfo[i];
}
/* iterate over each instruction. */
for (input_i = 0; ret == 0 && input_i < input->instlen; ++input_i)
{
xd3_winst *iinst = &input->inst[input_i];
switch (iinst->type)
{
case XD3_RUN:
ret = xd3_merge_run (stream, input, iinst);
break;
case XD3_ADD:
ret = xd3_merge_add (stream, input, iinst);
break;
default:
/* TODO: VCD_TARGET support is completely untested all
* throughout. */
if (iinst->mode == 0 || iinst->mode == VCD_TARGET)
{
ret = xd3_merge_target_copy (stream, iinst);
}
else
{
ret = xd3_merge_source_copy (stream, source, iinst);
}
/* The whole_target.length is not updated in the xd3_merge*copy
* routine because of recursion in xd3_merge_source_copy. */
stream->whole_target.length += iinst->size;
break;
}
}
return ret;
}
#endif

315
3rdparty/xdelta3-3.0.8/xdelta3-second.h vendored Normal file
View File

@@ -0,0 +1,315 @@
/* xdelta 3 - delta compression tools and library
* Copyright (C) 2002, 2003, 2006, 2007, 2013. Joshua P. MacDonald
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _XDELTA3_SECOND_H_
#define _XDELTA3_SECOND_H_
static inline void xd3_bit_state_encode_init (bit_state *bits)
{
bits->cur_byte = 0;
bits->cur_mask = 1;
}
static inline int xd3_decode_bits (xd3_stream *stream,
bit_state *bits,
const uint8_t **input,
const uint8_t *input_max,
usize_t nbits,
usize_t *valuep)
{
usize_t value = 0;
usize_t vmask = 1 << nbits;
if (bits->cur_mask == 0x100) { goto next_byte; }
for (;;)
{
do
{
vmask >>= 1;
if (bits->cur_byte & bits->cur_mask)
{
value |= vmask;
}
bits->cur_mask <<= 1;
if (vmask == 1) { goto done; }
}
while (bits->cur_mask != 0x100);
next_byte:
if (*input == input_max)
{
stream->msg = "secondary decoder end of input";
return XD3_INTERNAL;
}
bits->cur_byte = *(*input)++;
bits->cur_mask = 1;
}
done:
IF_DEBUG2 (DP(RINT "(d) %u ", value));
(*valuep) = value;
return 0;
}
#if REGRESSION_TEST
/* There may be extra bits at the end of secondary decompression, this macro
* checks for non-zero bits. This is overly strict, but helps pass the
* single-bit-error regression test. */
static int
xd3_test_clean_bits (xd3_stream *stream, bit_state *bits)
{
for (; bits->cur_mask != 0x100; bits->cur_mask <<= 1)
{
if (bits->cur_byte & bits->cur_mask)
{
stream->msg = "secondary decoder garbage";
return XD3_INTERNAL;
}
}
return 0;
}
#endif
static int
xd3_get_secondary (xd3_stream *stream, xd3_sec_stream **sec_streamp,
int is_encode)
{
if (*sec_streamp == NULL)
{
int ret;
if ((*sec_streamp = stream->sec_type->alloc (stream)) == NULL)
{
stream->msg = "error initializing secondary stream";
return XD3_INVALID;
}
if ((ret = stream->sec_type->init (stream, *sec_streamp, is_encode)) != 0)
{
return ret;
}
}
return 0;
}
static int
xd3_decode_secondary (xd3_stream *stream,
xd3_desect *sect,
xd3_sec_stream **sec_streamp)
{
uint32_t dec_size;
uint8_t *out_used;
int ret;
if ((ret = xd3_get_secondary (stream, sec_streamp, 0)) != 0)
{
return ret;
}
/* Decode the size, allocate the buffer. */
if ((ret = xd3_read_size (stream, & sect->buf,
sect->buf_max, & dec_size)) ||
(ret = xd3_decode_allocate (stream, dec_size,
& sect->copied2, & sect->alloc2)))
{
return ret;
}
out_used = sect->copied2;
if ((ret = stream->sec_type->decode (stream, *sec_streamp,
& sect->buf, sect->buf_max,
& out_used, out_used + dec_size)))
{
return ret;
}
if (sect->buf != sect->buf_max)
{
stream->msg = "secondary decoder finished with unused input";
return XD3_INTERNAL;
}
if (out_used != sect->copied2 + dec_size)
{
stream->msg = "secondary decoder short output";
return XD3_INTERNAL;
}
sect->buf = sect->copied2;
sect->buf_max = sect->copied2 + dec_size;
sect->size = dec_size;
return 0;
}
#if XD3_ENCODER
static inline int xd3_encode_bit (xd3_stream *stream,
xd3_output **output,
bit_state *bits,
usize_t bit)
{
int ret;
if (bit)
{
bits->cur_byte |= bits->cur_mask;
}
/* OPT: Might help to buffer more than 8 bits at once. */
if (bits->cur_mask == 0x80)
{
if ((ret = xd3_emit_byte (stream, output, bits->cur_byte)) != 0)
{
return ret;
}
bits->cur_mask = 1;
bits->cur_byte = 0;
}
else
{
bits->cur_mask <<= 1;
}
return 0;
}
static inline int xd3_flush_bits (xd3_stream *stream,
xd3_output **output,
bit_state *bits)
{
return (bits->cur_mask == 1) ? 0 :
xd3_emit_byte (stream, output, bits->cur_byte);
}
static inline int xd3_encode_bits (xd3_stream *stream,
xd3_output **output,
bit_state *bits,
usize_t nbits,
usize_t value)
{
int ret;
usize_t mask = 1 << nbits;
XD3_ASSERT (nbits > 0);
XD3_ASSERT (nbits < sizeof (usize_t) * 8);
XD3_ASSERT (value < mask);
do
{
mask >>= 1;
if ((ret = xd3_encode_bit (stream, output, bits, value & mask)))
{
return ret;
}
}
while (mask != 1);
IF_DEBUG2 (DP(RINT "(e) %u ", value));
return 0;
}
static int
xd3_encode_secondary (xd3_stream *stream,
xd3_output **head,
xd3_output **tail,
xd3_sec_stream **sec_streamp,
xd3_sec_cfg *cfg,
int *did_it)
{
xd3_output *tmp_head;
xd3_output *tmp_tail;
usize_t comp_size;
usize_t orig_size;
int ret;
orig_size = xd3_sizeof_output (*head);
if (orig_size < SECONDARY_MIN_INPUT) { return 0; }
if ((ret = xd3_get_secondary (stream, sec_streamp, 1)) != 0)
{
return ret;
}
tmp_head = xd3_alloc_output (stream, NULL);
/* Encode the size, encode the data. Encoding the size makes it
* simpler, but is a little gross. Should not need the entire
* section in contiguous memory, but it is much easier this way. */
if ((ret = xd3_emit_size (stream, & tmp_head, orig_size)) ||
(ret = stream->sec_type->encode (stream, *sec_streamp, *head,
tmp_head, cfg)))
{
goto getout;
}
/* If the secondary compressor determines it's no good, it returns
* XD3_NOSECOND. */
/* Setup tmp_tail, comp_size */
tmp_tail = tmp_head;
comp_size = tmp_head->next;
while (tmp_tail->next_page != NULL)
{
tmp_tail = tmp_tail->next_page;
comp_size += tmp_tail->next;
}
XD3_ASSERT (comp_size == xd3_sizeof_output (tmp_head));
XD3_ASSERT (tmp_tail != NULL);
if (comp_size < (orig_size - SECONDARY_MIN_SAVINGS) || cfg->inefficient)
{
IF_DEBUG1(DP(RINT "secondary saved %u bytes: %u -> %u (%0.2f%%)\n",
orig_size - comp_size, orig_size, comp_size,
100.0 * (double) comp_size / (double) orig_size));
xd3_free_output (stream, *head);
*head = tmp_head;
*tail = tmp_tail;
*did_it = 1;
}
else
{
getout:
if (ret == XD3_NOSECOND) { ret = 0; }
xd3_free_output (stream, tmp_head);
}
return ret;
}
#endif /* XD3_ENCODER */
#endif /* _XDELTA3_SECOND_H_ */

2872
3rdparty/xdelta3-3.0.8/xdelta3-test.h vendored Normal file

File diff suppressed because it is too large Load Diff

5497
3rdparty/xdelta3-3.0.8/xdelta3.c vendored Normal file

File diff suppressed because it is too large Load Diff

1373
3rdparty/xdelta3-3.0.8/xdelta3.h vendored Normal file

File diff suppressed because it is too large Load Diff