This commit moves all of the libraries under a common directory called libs/. This most certainly break libcxx and uClibc++ for now.

Squashed commit of the following:

    libs/libxx:  Fix some confusing in naming.  If the directory is called libxx, then the library must be libxx.a (unless perhaps LIBCXX is selected).
    libs/:  Fix paths in moved library directories.
    libs:  Brute force move of libc, libnx, and libxx to libs.  Cannot yet build it in that configuration.
This commit is contained in:
Gregory Nutt
2018-05-29 13:21:26 -06:00
parent 53a4408428
commit cf99fb40c9
836 changed files with 987 additions and 974 deletions
+61
View File
@@ -0,0 +1,61 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config LIBC_LZF
bool "LZF compression"
default n
---help---
Enable the LZF compression library from Marc Alexander Lehmann
if LIBC_LZF
choice
prompt "Compression options"
default LIBC_LZF_SMALL
---help---
Trade-offs between faster and smaller compression. These sections
have no effect on decompression.
config LIBC_LZF_SMALL
bool "Better compression"
config LIBC_LZF_FAST
bool "Faster compression"
config LIBC_LZF_FASTEST
bool "Fastest compression"
endchoice # Compression options
config LIBC_LZF_HLOG
int "Log2 Hash table size"
default 13
range 1 22
---help---
Size of hashtable is (1 << HLOG) * sizeof (char *). Decompression is
independent of the hash table size the difference between 15 and 14 is
very small for small blocks (and 14 is usually a bit faster). For a
low-memory/faster configuration, use HLOG == 13; For best compression,
use 15 or 16 (or more, up to 22).
Memory usage for the hash table will be approximately:
4 * (1 << CONFIG_LIBC_LZF_HLOG)
For the default setting of 13, this is 32Kb. A setting of 12 would
be half that or about 16Kb.
The application calling lzf_compress() must provide the hash table to
the compressor and may allocate that memory in the most efficient way
for the application. The hash table is not necessary if your application
only decompresses.
config LIBC_LZF_ALIGN
bool "Strict alignment"
default y
---help---
Unconditionally aligning does not cost very much, so do it if unsure.
endif # LIBC_LZF
+47
View File
@@ -0,0 +1,47 @@
############################################################################
# libs/libc/lzf/Make.defs
#
# Copyright (C) 2018 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
ifeq ($(CONFIG_LIBC_LZF),y)
# Add the internal C files to the build
CSRCS += lzf_c.c lzf_d.c
# Add the userfs directory to the build
DEPPATH += --dep-path lzf
VPATH += :lzf
endif
+93
View File
@@ -0,0 +1,93 @@
/****************************************************************************
* libs/libc/lzf/lzf.h
*
* Copyright (c) 2000-2007 Marc Alexander Lehmann <schmorp@schmorp.de>
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __LIBC_LZF_LZF_H
#define __LIBC_LZF_LZF_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifdef __cplusplus
# include <cstdint>
# include <cstring>
# include <climits>
# include <cerrno>
using namespace std;
#else
# include <stdint.h>
# include <string.h>
# include <limits.h>
# include <errno.h>
#endif
#include <lzf.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* You may choose to pre-set the hash table (might be faster on some modern
* CPUs and large (>>64k) blocks, and also makes compression deterministic/
* repeatable when the configuration otherwise is the same).
*/
#ifndef INIT_HTAB
# define INIT_HTAB 0
#endif
/* Whether to add extra checks for input validity in lzf_decompress
* and return EINVAL if the input stream has been corrupted. This
* only shields against overflowing the input buffer and will not
* detect most corrupted streams.
* This check is not normally noticeable on modern hardware
* (<1% slowdown), but might slow down older cpus considerably.
*/
#ifndef CHECK_INPUT
# define CHECK_INPUT 1
#endif
/* Whether to store pointers or offsets inside the hash table. On
* 64 bit architectures, pointers take up twice as much space,
* and might also be slower. Default is to autodetect.
*/
/*#define LZF_USER_OFFSETS autodetect */
#ifndef LZF_USE_OFFSETS
# define LZF_USE_OFFSETS (UINTPTR_MAX > 0xffffffffU)
#endif
/****************************************************************************
* Public Types
****************************************************************************/
#endif /* __LIBC_LZF_LZF_H */
+466
View File
@@ -0,0 +1,466 @@
/****************************************************************************
* libs/libc/lzf/lzf_c.c
*
* Copyright (c) 2000-2010 Marc Alexander Lehmann <schmorp@schmorp.de>
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include "lzf/lzf.h"
#ifdef CONFIG_LIBC_LZF
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define HSIZE (1 << HLOG)
/* Don't play with this unless you benchmark! The data format is not
* dependent on the hash function. The hash function might seem strange, just
* believe me, it works ;)
*/
#ifndef FRST
# define FRST(p) (((p[0]) << 8) | p[1])
# define NEXT(v,p) (((v) << 8) | p[2])
# if defined(CONFIG_LIBC_LZF_FASTEST)
# define IDX(h) ((( h >> (3*8 - HLOG)) - h ) & (HSIZE - 1))
# elif defined(CONFIG_LIBC_LZF_FAST)
# define IDX(h) ((( h >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
# else
# define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
# endif
#endif
/* IDX works because it is very similar to a multiplicative hash, e.g.
* ((h * 57321 >> (3*8 - HLOG)) & (HSIZE - 1))
* the latter is also quite fast on newer CPUs, and compresses similarly.
*
* the next one is also quite good, albeit slow ;)
* (int)(cos(h & 0xffffff) * 1e6)
*/
#if 0
/* original lzv-like hash function, much worse and thus slower */
# define FRST(p) (p[0] << 5) ^ p[1]
# define NEXT(v,p) ((v) << 5) ^ p[2]
# define IDX(h) ((h) & (HSIZE - 1))
#endif
#define MAX_LIT (1 << 5)
#define MAX_OFF (1 << HLOG)
#define MAX_REF ((1 << 8) + (1 << 3))
#if __GNUC__ >= 3
# define expect(expr,value) __builtin_expect((expr),(value))
# define inline inline
#else
# define expect(expr,value) (expr)
# define inline static
#endif
#define expect_false(expr) expect((expr) != 0, 0)
#define expect_true(expr) expect((expr) != 0, 1)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: lzf_compress
*
* Description:
* Compress in_len bytes stored at the memory block starting at
* in_data and write the result to out_data, up to a maximum length
* of out_len bytes.
*
* If the output buffer is not large enough or any error occurs return 0,
* otherwise return the number of bytes used, which might be considerably
* more than in_len (but less than 104% of the original size), so it
* makes sense to always use out_len == in_len - 1), to ensure _some_
* compression, and store the data uncompressed otherwise (with a flag, of
* course.
*
* lzf_compress might use different algorithms on different systems and
* even different runs, thus might result in different compressed strings
* depending on the phase of the moon or similar factors. However, all
* these strings are architecture-independent and will result in the
* original data when decompressed using lzf_decompress.
*
* The buffers must not be overlapping.
*
* Compressed format:
*
* 000LLLLL <L+1> ; literal, L+1=1..33 octets
* LLLooooo oooooooo ; backref L+1=1..7 octets, o+1=1..4096 offset
* 111ooooo LLLLLLLL oooooooo ; backref L+8 octets, o+1=1..4096 offset
*
****************************************************************************/
size_t lzf_compress(FAR const void *const in_data,
unsigned int in_len, FAR void *out_data,
unsigned int out_len, lzf_state_t htab,
FAR struct lzf_header_s **reshdr)
{
FAR const uint8_t *ip = (const uint8_t *)in_data;
FAR uint8_t *op = (uint8_t *)out_data;
FAR const uint8_t *in_end = ip + in_len;
FAR uint8_t *out_end = op + out_len;
FAR const uint8_t *ref;
ssize_t cs;
ssize_t retlen;
/* off requires a type wide enough to hold a general pointer difference.
* ISO C doesn't have that (size_t might not be enough and ptrdiff_t only
* works for differences within a single object). We also assume that no
* no bit pattern traps. Since the only platform that is both non-POSIX
* and fails to support both assumptions is windows 64 bit, we make a
* special workaround for it.
*/
#ifdef CONFIG_HAVE_LONG_LONG
uint64_t off; /* Workaround for missing POSIX compliance */
#else
unsigned long off;
#endif
unsigned int hval;
int lit;
if (!in_len || !out_len)
{
cs = 0;
goto genhdr;
}
#if INIT_HTAB
memset(htab, 0, sizeof(htab));
#endif
lit = 0; /* start run */
op++;
hval = FRST(ip);
while (ip < in_end - 2)
{
lzf_hslot_t *hslot;
hval = NEXT(hval, ip);
hslot = htab + IDX(hval);
ref = *hslot + LZF_HSLOT_BIAS;
*hslot = ip - LZF_HSLOT_BIAS;
if (1
#if INIT_HTAB
&& ref < ip /* the next test will actually take care of this, but this is faster */
#endif
&& (off = ip - ref - 1) < MAX_OFF
&& ref > (uint8_t *)in_data
&& ref[2] == ip[2]
#ifdef CONFIG_LIBC_LZF_ALIGN
&& ((ref[1] << 8) | ref[0]) == ((ip[1] << 8) | ip[0])
#else
&& *(uint16_t *)ref == *(uint16_t *)ip
#endif
)
{
/* Match found at *ref++ */
unsigned int len = 2;
unsigned int maxlen = in_end - ip - len;
maxlen = maxlen > MAX_REF ? MAX_REF : maxlen;
/* First a faster conservative test */
if (expect_false(op + 3 + 1 >= out_end))
{
/* Second the exact but rare test */
if (op - !lit + 3 + 1 >= out_end)
{
cs = 0;
goto genhdr;
}
}
op[- lit - 1] = lit - 1; /* Stop run */
op -= !lit; /* Undo run if length is zero */
for (;;)
{
if (expect_true(maxlen > 16))
{
len++;
if (ref[len] != ip[len])
{
break;
}
len++;
if (ref[len] != ip[len])
{
break;
}
len++;
if (ref[len] != ip[len])
{
break;
}
len++;
if (ref[len] != ip[len])
{
break;
}
len++;
if (ref[len] != ip[len])
{
break;
}
len++;
if (ref[len] != ip[len])
{
break;
}
len++;
if (ref[len] != ip[len])
{
break;
}
len++;
if (ref[len] != ip[len])
{
break;
}
len++;
if (ref[len] != ip[len])
{
break;
}
len++;
if (ref[len] != ip[len])
{
break;
}
len++;
if (ref[len] != ip[len])
{
break;
}
len++;
if (ref[len] != ip[len])
{
break;
}
len++;
if (ref[len] != ip[len])
{
break;
}
len++;
if (ref[len] != ip[len])
{
break;
}
len++;
if (ref[len] != ip[len])
{
break;
}
len++;
if (ref[len] != ip[len])
{
break;
}
}
do
{
len++;
}
while (len < maxlen && ref[len] == ip[len]);
break;
}
len -= 2; /* len is now #octets - 1 */
ip++;
if (len < 7)
{
*op++ = (off >> 8) + (len << 5);
}
else
{
*op++ = (off >> 8) + ( 7 << 5);
*op++ = len - 7;
}
*op++ = off;
lit = 0; op++; /* start run */
ip += len + 1;
if (expect_false (ip >= in_end - 2))
{
break;
}
#if defined(CONFIG_LIBC_LZF_FASTEST) || defined(CONFIG_LIBC_LZF_FAST)
--ip;
# if defined(CONFIG_LIBC_LZF_FAST) && !defined(CONFIG_LIBC_LZF_FASTEST)
--ip;
# endif
hval = FRST(ip);
hval = NEXT(hval, ip);
htab[IDX(hval)] = ip - LZF_HSLOT_BIAS;
ip++;
# if defined(CONFIG_LIBC_LZF_FAST) && !defined(CONFIG_LIBC_LZF_FASTEST)
hval = NEXT(hval, ip);
htab[IDX(hval)] = ip - LZF_HSLOT_BIAS;
ip++;
# endif
#else
ip -= len + 1;
do
{
hval = NEXT(hval, ip);
htab[IDX(hval)] = ip - LZF_HSLOT_BIAS;
ip++;
}
while (len--);
#endif
}
else
{
/* One more literal byte we must copy */
if (expect_false(op >= out_end))
{
cs = 0;
goto genhdr;
}
lit++;
*op++ = *ip++;
if (expect_false(lit == MAX_LIT))
{
op[- lit - 1] = lit - 1; /* Stop run */
lit = 0; /* Start run */
op++;
}
}
}
/* At most 3 bytes can be missing here */
if (op + 3 > out_end)
{
cs = 0;
goto genhdr;
}
while (ip < in_end)
{
lit++; *op++ = *ip++;
if (expect_false(lit == MAX_LIT))
{
op[- lit - 1] = lit - 1; /* Stop run */
lit = 0; /* Start run */
op++;
}
}
op[- lit - 1] = lit - 1; /* End run */
op -= !lit; /* Undo run if length is zero */
cs = op - (uint8_t *)out_data;
genhdr:
if (cs)
{
FAR struct lzf_type1_header_s *header;
/* Write compressed */
header = (FAR struct lzf_type1_header_s *)
((uintptr_t)out_data - LZF_TYPE1_HDR_SIZE);
header->lzf_magic[0] = 'Z';
header->lzf_magic[1] = 'V';
header->lzf_type = LZF_TYPE1_HDR;
header->lzf_clen[0] = cs >> 8;
header->lzf_clen[1] = cs & 0xff;
header->lzf_ulen[0] = in_len >> 8;
header->lzf_ulen[1] = in_len & 0xff;
*reshdr = (FAR struct lzf_header_s *)header;
retlen = cs + LZF_TYPE1_HDR_SIZE;
}
else
{
FAR struct lzf_type0_header_s *header;
/* Write uncompressed */
header = (FAR struct lzf_type0_header_s *)
((uintptr_t)in_data - LZF_TYPE0_HDR_SIZE);
header->lzf_magic[0] = 'Z';
header->lzf_magic[1] = 'V';
header->lzf_type = LZF_TYPE0_HDR;
header->lzf_len[0] = in_len >> 8;
header->lzf_len[1] = in_len & 0xff;
*reshdr = (FAR struct lzf_header_s *)header;
retlen = in_len + LZF_TYPE0_HDR_SIZE;
}
return retlen;
}
#endif /* CONFIG_LIBC_LZF */
+304
View File
@@ -0,0 +1,304 @@
/****************************************************************************
* libs/libc/lzf/lzf_c.c
*
* Copyright (c) 2000-2010 Marc Alexander Lehmann <schmorp@schmorp.de>
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include "lzf/lzf.h"
#ifdef CONFIG_LIBC_LZF
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: lzf_decompress
*
* Description:
* Decompress data compressed with some version of the lzf_compress
* function and stored at location in_data and length in_len. The result
* will be stored at out_data up to a maximum of out_len characters.
*
* If the output buffer is not large enough to hold the decompressed
* data, a 0 is returned and errno is set to E2BIG. Otherwise the number
* of decompressed bytes (i.e. the original length of the data) is
* returned.
*
* If an error in the compressed data is detected, a zero is returned and
* errno is set to EINVAL.
*
* This function is very fast, about as fast as a copying loop.
*
****************************************************************************/
unsigned int lzf_decompress (FAR const void *const in_data,
unsigned int in_len, FAR void *out_data,
unsigned int out_len)
{
FAR uint8_t const *ip = (const uint8_t *)in_data;
FAR uint8_t *op = (uint8_t *)out_data;
FAR uint8_t const *const in_end = ip + in_len;
FAR uint8_t *const out_end = op + out_len;
do
{
unsigned int ctrl = *ip++;
if (ctrl < (1 << 5)) /* literal run */
{
ctrl++;
if (op + ctrl > out_end)
{
set_errno(E2BIG);
return 0;
}
#if CHECK_INPUT
if (ip + ctrl > in_end)
{
set_errno(EINVAL);
return 0;
}
#endif
#ifdef lzf_movsb
lzf_movsb(op, ip, ctrl);
#else
switch (ctrl)
{
case 32:
*op++ = *ip++;
case 31:
*op++ = *ip++;
case 30:
*op++ = *ip++;
case 29:
*op++ = *ip++;
case 28:
*op++ = *ip++;
case 27:
*op++ = *ip++;
case 26:
*op++ = *ip++;
case 25:
*op++ = *ip++;
case 24:
*op++ = *ip++;
case 23:
*op++ = *ip++;
case 22:
*op++ = *ip++;
case 21:
*op++ = *ip++;
case 20:
*op++ = *ip++;
case 19:
*op++ = *ip++;
case 18:
*op++ = *ip++;
case 17:
*op++ = *ip++;
case 16:
*op++ = *ip++;
case 15:
*op++ = *ip++;
case 14:
*op++ = *ip++;
case 13:
*op++ = *ip++;
case 12:
*op++ = *ip++;
case 11:
*op++ = *ip++;
case 10:
*op++ = *ip++;
case 9:
*op++ = *ip++;
case 8:
*op++ = *ip++;
case 7:
*op++ = *ip++;
case 6:
*op++ = *ip++;
case 5:
*op++ = *ip++;
case 4:
*op++ = *ip++;
case 3:
*op++ = *ip++;
case 2:
*op++ = *ip++;
case 1:
*op++ = *ip++;
}
#endif
}
else /* back reference */
{
unsigned int len = ctrl >> 5;
FAR uint8_t *ref = op - ((ctrl & 0x1f) << 8) - 1;
#if CHECK_INPUT
if (ip >= in_end)
{
set_errno(EINVAL);
return 0;
}
#endif
if (len == 7)
{
len += *ip++;
#if CHECK_INPUT
if (ip >= in_end)
{
set_errno(EINVAL);
return 0;
}
#endif
}
ref -= *ip++;
if (op + len + 2 > out_end)
{
set_errno(E2BIG);
return 0;
}
if (ref < (uint8_t *)out_data)
{
set_errno(EINVAL);
return 0;
}
#ifdef lzf_movsb
len += 2;
lzf_movsb(op, ref, len);
#else
switch (len)
{
default:
len += 2;
if (op >= ref + len)
{
/* Disjunct areas */
memcpy (op, ref, len);
op += len;
}
else
{
/* Overlapping, use octet by octet copying */
do
{
*op++ = *ref++;
}
while (--len);
}
break;
case 9:
*op++ = *ref++;
case 8:
*op++ = *ref++;
case 7:
*op++ = *ref++;
case 6:
*op++ = *ref++;
case 5:
*op++ = *ref++;
case 4:
*op++ = *ref++;
case 3:
*op++ = *ref++;
case 2:
*op++ = *ref++;
case 1:
*op++ = *ref++;
case 0:
/* Two octets more */
*op++ = *ref++;
*op++ = *ref++;
}
#endif
}
}
while (ip < in_end);
return op - (uint8_t *)out_data;
}
#endif /* CONFIG_LIBC_LZF */