home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1997 March / PCO3_97.ISO / filesbbs / os2 / lzo026.arj / LZO026.ZIP / lzo-0.26 / src / lzo_util.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-16  |  11.1 KB  |  463 lines

  1. /* lzo_util.c -- utilities for the the LZO library
  2.  
  3.    This file is part of the LZO real-time data compression library.
  4.  
  5.    Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
  6.  
  7.    The LZO library is free software; you can redistribute it and/or
  8.    modify it under the terms of the GNU General Public License as
  9.    published by the Free Software Foundation; either version 2 of
  10.    the License, or (at your option) any later version.
  11.  
  12.    The LZO library is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with the LZO library; see the file COPYING.
  19.    If not, write to the Free Software Foundation, Inc.,
  20.    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21.  
  22.    Markus F.X.J. Oberhumer
  23.    markus.oberhumer@jk.uni-linz.ac.at
  24.  */
  25.  
  26.  
  27. #include <stdio.h>
  28.  
  29. #include "lzo_conf.h"
  30. #include "lzo_util.h"
  31.  
  32.  
  33.  
  34. /***********************************************************************
  35. // slow but portable <string.h> stuff, only used in assertions
  36. ************************************************************************/
  37.  
  38. LZO_PUBLIC(int)
  39. lzo_memcmp(const lzo_voidp s1, const lzo_voidp s2, lzo_uint len)
  40. {
  41. #if (LZO_UINT_MAX <= UINT_MAX) && !defined(MFX_MEMCMP_BROKEN)
  42.     return memcmp(s1,s2,len);
  43. #else
  44.     const lzo_byte *p1 = (const lzo_byte *) s1;
  45.     const lzo_byte *p2 = (const lzo_byte *) s2;
  46.     int d;
  47.  
  48.     if (len > 0) do
  49.     {
  50.         d = *p1 - *p2;
  51.         if (d != 0)
  52.             return d;
  53.         p1++;
  54.         p2++;
  55.     }
  56.     while (--len > 0);
  57.     return 0;
  58. #endif
  59. }
  60.  
  61.  
  62. LZO_PUBLIC(lzo_voidp)
  63. lzo_memcpy(lzo_voidp dest, const lzo_voidp src, lzo_uint len)
  64. {
  65. #if (LZO_UINT_MAX <= UINT_MAX)
  66.     return memcpy(dest,src,len);
  67. #else
  68.     lzo_byte *p1 = (lzo_byte *) dest;
  69.     const lzo_byte *p2 = (const lzo_byte *) src;
  70.  
  71.     if (len <= 0 || p1 == p2)
  72.         return dest;
  73.     do
  74.         *p1++ = *p2++;
  75.     while (--len > 0);
  76.     return dest;
  77. #endif
  78. }
  79.  
  80.  
  81. LZO_PUBLIC(lzo_voidp)
  82. lzo_memmove(lzo_voidp dest, const lzo_voidp src, lzo_uint len)
  83. {
  84. #if (LZO_UINT_MAX <= UINT_MAX) && !defined(MFX_MEMMOVE_BROKEN)
  85.     return memmove(dest,src,len);
  86. #else
  87.     lzo_byte *p1 = (lzo_byte *) dest;
  88.     const lzo_byte *p2 = (const lzo_byte *) src;
  89.  
  90.     if (len <= 0 || p1 == p2)
  91.         return dest;
  92.  
  93.     if (p1 < p2)
  94.     {
  95.         do
  96.             *p1++ = *p2++;
  97.         while (--len > 0);
  98.     }
  99.     else
  100.     {
  101.         p1 += len;
  102.         p2 += len;
  103.         do
  104.             *--p1 = *--p2;
  105.         while (--len > 0);
  106.     }
  107.     return dest;
  108. #endif
  109. }
  110.  
  111.  
  112. LZO_PUBLIC(lzo_voidp)
  113. lzo_memset(lzo_voidp s, int c, lzo_uint len)
  114. {
  115. #if (LZO_UINT_MAX <= UINT_MAX)
  116.     return memset(s,c,len);
  117. #else
  118.     lzo_byte *p = (lzo_byte *) s;
  119.  
  120.     if (len > 0) do
  121.         *p++ = LZO_BYTE(c);
  122.     while (--len > 0);
  123.     return s;
  124. #endif
  125. }
  126.  
  127.  
  128. /***********************************************************************
  129. // adler32 checksum
  130. // adapted from free code by Mark Adler <madler@alumni.caltech.edu>
  131. // see http://quest.jpl.nasa.gov/zlib
  132. ************************************************************************/
  133.  
  134. #define LZO_BASE 65521u /* largest prime smaller than 65536 */
  135. #define LZO_NMAX 5552
  136. /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
  137.  
  138. #define LZO_DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
  139. #define LZO_DO2(buf,i)  LZO_DO1(buf,i); LZO_DO1(buf,i+1);
  140. #define LZO_DO4(buf,i)  LZO_DO2(buf,i); LZO_DO2(buf,i+2);
  141. #define LZO_DO8(buf,i)  LZO_DO4(buf,i); LZO_DO4(buf,i+4);
  142. #define LZO_DO16(buf)   LZO_DO8(buf,0); LZO_DO8(buf,8);
  143.  
  144. LZO_PUBLIC(lzo_uint32)
  145. lzo_adler32(lzo_uint32 adler, const lzo_byte *buf, lzo_uint len)
  146. {
  147.     lzo_uint32 s1 = adler & 0xffff;
  148.     lzo_uint32 s2 = (adler >> 16) & 0xffff;
  149.     int k;
  150.  
  151.     if (buf == NULL)
  152.         return 1;
  153.  
  154.     while (len > 0)
  155.     {
  156.         k = len < LZO_NMAX ? (int) len : LZO_NMAX;
  157.         len -= k;
  158.         if (k >= 16) do
  159.         {
  160.             LZO_DO16(buf);
  161.             buf += 16;
  162.             k -= 16;
  163.         } while (k >= 16);
  164.         if (k != 0) do
  165.         {
  166.             s1 += *buf++;
  167.             s2 += s1;
  168.         } while (--k);
  169.         s1 %= LZO_BASE;
  170.         s2 %= LZO_BASE;
  171.     }
  172.     return (s2 << 16) | s1;
  173. }
  174.  
  175. #undef LZO_BASE
  176. #undef LZO_NMAX
  177. #undef LZO_DO1
  178. #undef LZO_DO2
  179. #undef LZO_DO4
  180. #undef LZO_DO8
  181. #undef LZO_DO16
  182.  
  183.  
  184. /***********************************************************************
  185. // Runtime check of the assumptions about the size of builtin types,
  186. // memory model, byte order and other low-level constructs.
  187. // We are really paranoid here.
  188. // Because of inlining much of this function evaluates to nothing.
  189. ************************************************************************/
  190.  
  191. #ifndef __cplusplus            /* work around a bug (?) in g++ 2.6.3 */
  192. __inline__
  193. #endif
  194. LZO_PUBLIC(lzo_bool)
  195. lzo_assert(int expr)
  196. {
  197.     return (expr) ? 1 : 0;
  198. }
  199.  
  200. static lzo_bool strength_reduce_works_ok(int *);    /* avoid inlining */
  201.  
  202. LZO_PUBLIC(int)
  203. _lzo_config_check(void)
  204. {
  205.     lzo_bool r = 1;
  206.     int i;
  207.     lzo_uint32 adler;
  208.     char _wrkmem[8 * sizeof(lzo_byte *) + 16];
  209.     const lzo_bytepp const dict = (const lzo_bytepp) LZO_ALIGN(_wrkmem,16);
  210.     lzo_byte *wrkmem = (lzo_byte *) dict;
  211.  
  212.     r &= lzo_assert(sizeof(lzo_uint32) >= 4);
  213.     r &= lzo_assert(sizeof(lzo_uint32) >= sizeof(lzo_uint));
  214.     r &= lzo_assert(sizeof(lzo_uint) >= sizeof(unsigned));
  215.  
  216.     r &= lzo_assert(sizeof(lzo_ptrdiff_t) >= 4);
  217.     r &= lzo_assert(sizeof(lzo_ptrdiff_t) >= sizeof(ptrdiff_t));
  218.  
  219.     r &= lzo_assert(sizeof(lzo_voidp) >= sizeof(lzo_uint));
  220.     r &= lzo_assert(sizeof(lzo_voidp) == sizeof(lzo_byte *));
  221.     r &= lzo_assert(sizeof(lzo_voidp) == sizeof(lzo_voidpp));
  222.     r &= lzo_assert(sizeof(lzo_voidp) == sizeof(lzo_bytepp));
  223.     r &= lzo_assert(sizeof(lzo_voidp) == sizeof(dict[0]));
  224.  
  225.     r &= lzo_assert(sizeof(lzo_void_ptr_t) == sizeof(lzo_voidp));
  226.  
  227.     r &= lzo_assert(sizeof(lzo_ptr_t) >= 4);
  228.     r &= lzo_assert(sizeof(lzo_ptr_t) >= sizeof(lzo_voidp));
  229.     r &= lzo_assert(sizeof(lzo_ptr_t) >= sizeof(ptrdiff_t));
  230.     r &= lzo_assert(sizeof(lzo_ptr_t) >= sizeof(lzo_ptrdiff_t));
  231.  
  232. #if defined(SIZEOF_CHAR_P)
  233.     r &= lzo_assert(SIZEOF_CHAR_P == sizeof(char *));
  234.     r &= lzo_assert(sizeof(lzo_voidp) == sizeof(char *));
  235. #endif
  236. #if defined(SIZEOF_UNSIGNED)
  237.     r &= lzo_assert(SIZEOF_UNSIGNED == sizeof(unsigned));
  238. #endif
  239. #if defined(SIZEOF_UNSIGNED_LONG)
  240.     r &= lzo_assert(SIZEOF_UNSIGNED_LONG == sizeof(unsigned long));
  241. #endif
  242. #if defined(SIZEOF_UNSIGNED_SHORT)
  243.     r &= lzo_assert(SIZEOF_UNSIGNED_SHORT == sizeof(unsigned short));
  244. #endif
  245. #if defined(SIZEOF_PTRDIFF_T)
  246. #if (SIZEOF_PTRDIFF_T > 0)
  247.     r &= lzo_assert(SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t));
  248. #endif
  249. #endif
  250. #if defined(SIZEOF_SIZE_T)
  251. #if (SIZEOF_SIZE_T > 0)
  252.     r &= lzo_assert(SIZEOF_SIZE_T == sizeof(size_t));
  253. #endif
  254. #endif
  255.  
  256.     /* assert the signedness of the integral types */
  257. #define LZO_HIGHBIT(type)    ((type) (1ul << (CHAR_BIT * sizeof(type) - 1)))
  258.     r &= lzo_assert(LZO_HIGHBIT(lzo_uint32)      > 0);
  259.     r &= lzo_assert(LZO_HIGHBIT(lzo_int32)       < 0);
  260.     r &= lzo_assert(LZO_HIGHBIT(lzo_uint)        > 0);
  261.     r &= lzo_assert(LZO_HIGHBIT(lzo_int)         < 0);
  262.     r &= lzo_assert(LZO_HIGHBIT(lzo_ptrdiff_t)   < 0);
  263.     r &= lzo_assert(LZO_HIGHBIT(lzo_ptr_t)       > 0);
  264.     r &= lzo_assert(LZO_HIGHBIT(lzo_sptr_t)      < 0);
  265.     r &= lzo_assert(LZO_HIGHBIT(lzo_void_ptr_t)  > 0);
  266.     r &= lzo_assert(LZO_HIGHBIT(lzo_void_sptr_t) < 0);
  267. #undef LZO_HIGHBIT
  268.  
  269.     /* sanity check of the memory model */
  270.     if (r == 1)
  271.     {
  272.         for (i = 0; i < 8; i++)
  273.             r &= lzo_assert((lzo_voidp) (&dict[i]) ==
  274.                             (lzo_voidp) (&wrkmem[i * sizeof(lzo_byte *)]));
  275.     }
  276.  
  277.     /* check LZO_BYTE_ORDER */
  278. #if defined(LZO_BYTE_ORDER)
  279.     if (r == 1)
  280.     {
  281.         union {
  282.             unsigned char x[16];
  283.             lzo_uint32 a;
  284.             unsigned short b;
  285.         } u;
  286.  
  287.         for (i = 0; i < 8; i++)
  288.             u.x[i] = LZO_BYTE(i);
  289.  
  290. #  if (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
  291.         r &= lzo_assert((u.a & 0xffffffffL) == 0x03020100L);
  292.         r &= lzo_assert((u.b & 0xffff) == 0x0100);
  293. #  elif (LZO_BYTE_ORDER == LZO_BIG_ENDIAN)
  294.         r &= lzo_assert((u.a & 0xffffffffL) == 0x00010203L);
  295.         r &= lzo_assert((u.b & 0xffff) == 0x0001);
  296. #  else
  297. #    error invalid LZO_BYTE_ORDER
  298. #  endif
  299.     }
  300. #endif
  301.  
  302.     /* check that unaligned memory access works as expected */
  303. #if defined(LZO_UNALIGNED_OK_2)
  304.     r &= lzo_assert(sizeof(short) == 2);
  305.     if (r == 1)
  306.     {
  307.         unsigned char x[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
  308.         unsigned short b[4];
  309.  
  310.         for (i = 0; i < 4; i++)
  311.             b[i] = * (unsigned short *) &x[i];
  312.  
  313. #  if (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
  314.         r &= lzo_assert(b[0] == 0x0100);
  315.         r &= lzo_assert(b[1] == 0x0201);
  316.         r &= lzo_assert(b[2] == 0x0302);
  317.         r &= lzo_assert(b[3] == 0x0403);
  318. #  elif (LZO_BYTE_ORDER == LZO_BIG_ENDIAN)
  319.         r &= lzo_assert(b[0] == 0x0001);
  320.         r &= lzo_assert(b[1] == 0x0102);
  321.         r &= lzo_assert(b[2] == 0x0203);
  322.         r &= lzo_assert(b[3] == 0x0304);
  323. #  endif
  324.     }
  325. #endif
  326.  
  327. #if defined(LZO_UNALIGNED_OK_4)
  328.     r &= lzo_assert(sizeof(lzo_uint32) == 4);
  329.     if (r == 1)
  330.     {
  331.         unsigned char x[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
  332.         lzo_uint32 a[4];
  333.  
  334.         for (i = 0; i < 4; i++)
  335.             a[i] = * (lzo_uint32 *) &x[i];
  336.  
  337. #  if (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
  338.         r &= lzo_assert(a[0] == 0x03020100L);
  339.         r &= lzo_assert(a[1] == 0x04030201L);
  340.         r &= lzo_assert(a[2] == 0x05040302L);
  341.         r &= lzo_assert(a[3] == 0x06050403L);
  342. #  elif (LZO_BYTE_ORDER == LZO_BIG_ENDIAN)
  343.         r &= lzo_assert(a[0] == 0x00010203L);
  344.         r &= lzo_assert(a[1] == 0x01020304L);
  345.         r &= lzo_assert(a[2] == 0x02030405L);
  346.         r &= lzo_assert(a[3] == 0x03040506L);
  347. #  endif
  348.     }
  349. #endif
  350.  
  351.     /* check BZERO8_PTR and that NULL == 0 */
  352.     r &= lzo_assert(NULL == 0);
  353.     if (r == 1)
  354.     {
  355.         BZERO8_PTR(dict,8);
  356.         for (i = 0; i < 8; i++)
  357.             r &= lzo_assert(dict[i] == NULL);
  358.     }
  359.  
  360.     /* check the lzo_adler32() function */
  361.     if (r == 1)
  362.     {
  363.         adler = lzo_adler32(0, NULL, 0);
  364.         adler = lzo_adler32(adler, __lzo_copyright, 144);
  365.         r &= lzo_assert(adler == 0x845c30a2L);
  366.     }
  367.  
  368.     /* check for the gcc strength-reduction optimization bug */
  369.     if (r == 1)
  370.     {
  371.         static int x[3];
  372.         static unsigned xn = 3;
  373.         register unsigned j;
  374.  
  375.         for (j = 0; j < xn; j++)
  376.             x[j] = (int)j - 3;
  377.         r &= lzo_assert(strength_reduce_works_ok(x));
  378.     }
  379.  
  380.     return r == 1 ? LZO_E_OK : LZO_E_ERROR;
  381. }
  382.  
  383.  
  384. static lzo_bool strength_reduce_works_ok(int *x)
  385. {
  386.     return x[0] == -3 && x[1] == -2 && x[2] == -1;
  387. }
  388.  
  389.  
  390. /***********************************************************************
  391. //
  392. ************************************************************************/
  393.  
  394. /* If you use the LZO library in a product, you *must* keep this
  395.  * copyright string in the executable of your product.
  396.  */
  397.  
  398. const lzo_byte __lzo_copyright[] =
  399.     "\n\n\n"
  400.     "LZO real-time data compression library.\n"
  401.     "Copyright (C) 1996, 1997 Markus Franz Xaver Johannes Oberhumer\n"
  402.     "<markus.oberhumer@jk.uni-linz.ac.at>\n"
  403.     "\n"
  404.     "LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE "\n"
  405.     "LZO build date: " __DATE__ " " __TIME__ "\n"
  406.     "LZO special compilation options:\n"
  407. #ifdef __cplusplus
  408.     " __cplusplus\n"
  409. #endif
  410. #if (UINT_MAX < 0xffffffffL)
  411.     " 16BIT\n"
  412. #elif (UINT_MAX > 0xffffffffL)
  413.     " 64BIT\n"
  414. #endif
  415. #if (LZO_UINT_MAX < 0xffffffffL)
  416.     " LZO_16BIT\n"
  417. #endif
  418. #if defined(LZO_BYTE_ORDER)
  419.     " LZO_BYTE_ORDER=" _LZO_MEXPAND(LZO_BYTE_ORDER) "\n"
  420. #endif
  421. #if defined(LZO_UNALIGNED_OK_2)
  422.     " LZO_UNALIGNED_OK_2\n"
  423. #endif
  424. #if defined(LZO_UNALIGNED_OK_4)
  425.     " LZO_UNALIGNED_OK_4\n"
  426. #endif
  427.     "\n\n";
  428.  
  429.  
  430. LZO_PUBLIC(unsigned)
  431. lzo_version(void)
  432. {
  433.     return LZO_VERSION;
  434. }
  435.  
  436. LZO_PUBLIC(const char *)
  437. lzo_version_string(void)
  438. {
  439.     return LZO_VERSION_STRING;
  440. }
  441.  
  442.  
  443. /***********************************************************************
  444. //
  445. ************************************************************************/
  446.  
  447. LZO_PUBLIC(int)
  448. lzo_init(void)
  449. {
  450.     int r;
  451.  
  452.     r = _lzo_config_check();
  453.     if (r != LZO_E_OK)
  454.         return r;
  455.  
  456.     return r;
  457. }
  458.  
  459.  
  460. /*
  461. vi:ts=4
  462. */
  463.