Logo Search packages:      
Sourcecode: ksh version File versions

sumlib.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*           Copyright (c) 1996-2007 AT&T Knowledge Ventures            *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                      by AT&T Knowledge Ventures                      *
*                                                                      *
*                A copy of the License is available at                 *
*            http://www.opensource.org/licenses/cpl1.0.txt             *
*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
*                                                                      *
*              Information and Software Systems Research               *
*                            AT&T Research                             *
*                           Florham Park NJ                            *
*                                                                      *
*                 Glenn Fowler <gsf@research.att.com>                  *
*                                                                      *
***********************************************************************/
#pragma prototyped
/*
 * Glenn Fowler
 * AT&T Research
 *
 * man this is sum library
 */

static const char id[] = "\n@(#)$Id: sumlib (AT&T Research) 2007-03-11 $\0\n";

#define _SUM_PRIVATE_   \
                  struct Method_s*  method;     \
                  uintmax_t         total_count;      \
                  uintmax_t         total_size; \
                  uintmax_t         size;

#include <sum.h>
#include <ctype.h>
#include <swap.h>
#include <hashpart.h>

#define SCALE(n,m)      (((n)+(m)-1)/(m))

typedef struct Method_s
{
      const char* match;
      const char* description;
      const char* options;
      Sum_t*            (*open)(const struct Method_s*, const char*);
      int         (*init)(Sum_t*);
      int         (*block)(Sum_t*, const void*, size_t);
      int         (*data)(Sum_t*, Sumdata_t*);
      int         (*print)(Sum_t*, Sfio_t*, int);
      int         (*done)(Sum_t*);
      int         scale;
} Method_t;

typedef struct Map_s
{
      const char* match;
      const char* description;
      const char* map;
} Map_t;

/*
 * 16 and 32 bit common code
 */

#define _INTEGRAL_PRIVATE_ \
      uint32_t    sum; \
      uint32_t    total_sum;
      
typedef struct Integral_s
{
      _SUM_PUBLIC_
      _SUM_PRIVATE_
      _INTEGRAL_PRIVATE_
} Integral_t;

static Sum_t*
long_open(const Method_t* method, const char* name)
{
      Integral_t* p;

      if (p = newof(0, Integral_t, 1, 0))
      {
            p->method = (Method_t*)method;
            p->name = name;
      }
      return (Sum_t*)p;
}

static int
long_init(Sum_t* p)
{
      ((Integral_t*)p)->sum = 0;
      return 0;
}

static int
long_done(Sum_t* p)
{
      register Integral_t*    x = (Integral_t*)p;

      x->total_sum ^= (x->sum &= 0xffffffff);
      return 0;
}

static int
short_done(Sum_t* p)
{
      register Integral_t*    x = (Integral_t*)p;

      x->total_sum ^= (x->sum &= 0xffff);
      return 0;
}

static int
long_print(Sum_t* p, Sfio_t* sp, register int flags)
{
      register Integral_t*    x = (Integral_t*)p;
      register uint32_t c;
      register uintmax_t      z;
      register size_t         n;

      c = (flags & SUM_TOTAL) ? x->total_sum : x->sum;
      sfprintf(sp, "%I*u", sizeof(c), c);
      if (flags & SUM_SIZE)
      {
            z = (flags & SUM_TOTAL) ? x->total_size : x->size;
            if ((flags & SUM_SCALE) && (n = x->method->scale))
                  z = SCALE(z, n);
            sfprintf(sp, " %I*u", sizeof(z), z);
      }
      if (flags & SUM_TOTAL)
            sfprintf(sp, " %I*u", sizeof(x->total_count), x->total_count);
      return 0;
}

static int
long_data(Sum_t* p, Sumdata_t* data)
{
      register Integral_t*    x = (Integral_t*)p;

      data->size = sizeof(data->num);
      data->num = x->sum;
      data->buf = 0;
      return 0;
}

#include "sum-att.c"
#include "sum-ast4.c"
#include "sum-bsd.c"
#include "sum-crc.c"
#include "sum-md5.c"
#include "sum-prng.c"
#include "sum-sha1.c"
#include "sum-sha2.c"

/*
 * now the library interface
 */

#undef      METHOD            /* solaris <sys/localedef.h>! */
#define METHOD(x) x##_match,x##_description,x##_options,x##_open,x##_init,x##_block,x##_data,x##_print,x##_done,x##_scale

static const Method_t   methods[] =
{
      METHOD(att),
      METHOD(ast4),
      METHOD(bsd),
      METHOD(crc),
      METHOD(md5),
      METHOD(prng),
#ifdef sha1_description
      METHOD(sha1),
#endif
#ifdef sha256_description
      METHOD(sha256),
#endif
#ifdef sha384_description
      METHOD(sha384),
#endif
#ifdef sha512_description
      METHOD(sha512),
#endif
};

static const Map_t      maps[] =
{
      {
            "posix|cksum|std|standard",
            "The posix 1003.2-1992 32 bit crc checksum. This is the"
            " default \bcksum\b(1)  method.",
            "crc-0x04c11db7-rotate-done-size"
      },
      {
            "zip",
            "The \bzip\b(1) crc.",
            "crc-0xedb88320-init-done"
      },
      {
            "fddi",
            "The FDDI crc.",
            "crc-0xedb88320-size=0xcc55cc55"
      },
      {
            "fnv|fnv1",
            "The Fowler-Noll-Vo 32 bit PRNG hash with non-zero"
            " initializer (FNV-1).",
            "prng-0x01000193-init=0x811c9dc5"
      },
      {
            "ast|strsum",
            "The \bast\b \bstrsum\b(3) PRNG hash.",
            "prng-0x63c63cd9-add=0x9c39c33d"
      },
};

/*
 * open sum method name
 */

Sum_t*
sumopen(register const char* name)
{
      register int      n;
      char        pat[256];

      if (!name || !name[0] || name[0] == '-' && !name[1])
            name = "default";
      for (n = 0; n < elementsof(maps); n++)
      {
            sfsprintf(pat, sizeof(pat), "*@(%s)*", maps[n].match);
            if (strmatch(name, pat))
            {
                  name = maps[n].map;
                  break;
            }
      }
      for (n = 0; n < elementsof(methods); n++)
      {
            sfsprintf(pat, sizeof(pat), "*@(%s)*", methods[n].match);
            if (strmatch(name, pat))
                  return (*methods[n].open)(&methods[n], name);
      }
      return 0;
}

/*
 * initialize for a new run of blocks
 */

int
suminit(Sum_t* p)
{
      p->size = 0;
      return (*p->method->init)(p);
}

/*
 * compute the running sum on buf
 */

int
sumblock(Sum_t* p, const void* buf, size_t siz)
{
      p->size += siz;
      return (*p->method->block)(p, buf, siz);
}

/*
 * done with this run of blocks
 */

int
sumdone(Sum_t* p)
{
      p->total_count++;
      p->total_size += p->size;
      return (*p->method->done)(p);
}

/*
 * print the sum [size] on sp
 */

int
sumprint(Sum_t* p, Sfio_t* sp, int flags)
{
      return (*p->method->print)(p, sp, flags);
}

/*
 * return the current sum (internal) data
 */

int
sumdata(Sum_t* p, Sumdata_t* d)
{
      return (*p->method->data)(p, d);
}

/*
 * close an open sum handle
 */

int
sumclose(Sum_t* p)
{
      free(p);
      return 0;
}

/*
 * print the checksum method optget(3) usage on sp and return the length
 */

int
sumusage(Sfio_t* sp)
{
      register int      i;
      register int      n;

      for (i = n = 0; i < elementsof(methods); i++)
      {
            n += sfprintf(sp, "[+%s?%s]", methods[i].match, methods[i].description);
            if (methods[i].options)
                  n += sfprintf(sp, "{\n%s\n}", methods[i].options);
      }
      for (i = 0; i < elementsof(maps); i++)
            n += sfprintf(sp, "[+%s?%s Shorthand for \b%s\b.]", maps[i].match, maps[i].description, maps[i].map);
      return n;
}

Generated by  Doxygen 1.6.0   Back to index