1/* 2 * crc_zlib.c -- 3 * 4 * Implements and registers message digest generator CRC32 (taken from zlib). 5 * 6 * 7 * Copyright (c) 1996 Andreas Kupries (a.kupries@westend.com) 8 * All rights reserved. 9 * 10 * Permission is hereby granted, without written agreement and without 11 * license or royalty fees, to use, copy, modify, and distribute this 12 * software and its documentation for any purpose, provided that the 13 * above copyright notice and the following two paragraphs appear in 14 * all copies of this software. 15 * 16 * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, 17 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS 18 * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE 19 * POSSIBILITY OF SUCH DAMAGE. 20 * 21 * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND 24 * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 25 * ENHANCEMENTS, OR MODIFICATIONS. 26 * 27 * CVS: $Id: crc_zlib.c,v 1.5 2003/01/09 21:27:10 andreas_kupries Exp $ 28 */ 29 30#include "transformInt.h" 31 32/* 33 * Generator description 34 * --------------------- 35 * 36 * The CRC32 algorithm (contained in library 'zlib') 37 * is used to compute a message digest. 38 */ 39 40#define DIGEST_SIZE 4 /* byte == 32 bit */ 41#define CTX_TYPE uLong 42 43/* 44 * Declarations of internal procedures. 45 */ 46 47static void MDcrcz_Start _ANSI_ARGS_ ((VOID* context)); 48static void MDcrcz_Update _ANSI_ARGS_ ((VOID* context, unsigned int character)); 49static void MDcrcz_UpdateBuf _ANSI_ARGS_ ((VOID* context, unsigned char* buffer, int bufLen)); 50static void MDcrcz_Final _ANSI_ARGS_ ((VOID* context, VOID* digest)); 51static int MDcrcz_Check _ANSI_ARGS_ ((Tcl_Interp* interp)); 52 53/* 54 * Generator definition. 55 */ 56 57static Trf_MessageDigestDescription mdDescription = { 58 "crc-zlib", 59 sizeof (CTX_TYPE), 60 DIGEST_SIZE, 61 MDcrcz_Start, 62 MDcrcz_Update, 63 MDcrcz_UpdateBuf, 64 MDcrcz_Final, 65 MDcrcz_Check 66}; 67 68#define CRC (*((uLong*) context)) 69 70/* 71 *------------------------------------------------------* 72 * 73 * TrfInit_CRC_zlib -- 74 * 75 * ------------------------------------------------* 76 * Register the generator implemented in this file. 77 * ------------------------------------------------* 78 * 79 * Sideeffects: 80 * As of 'Trf_Register'. 81 * 82 * Result: 83 * A standard Tcl error code. 84 * 85 *------------------------------------------------------* 86 */ 87 88int 89TrfInit_CRC_ZLIB (interp) 90Tcl_Interp* interp; 91{ 92 return Trf_RegisterMessageDigest (interp, &mdDescription); 93} 94 95/* 96 *------------------------------------------------------* 97 * 98 * MDcrcz_Start -- 99 * 100 * ------------------------------------------------* 101 * Initialize the internal state of the message 102 * digest generator. 103 * ------------------------------------------------* 104 * 105 * Sideeffects: 106 * As of the called procedure. 107 * 108 * Result: 109 * None. 110 * 111 *------------------------------------------------------* 112 */ 113 114static void 115MDcrcz_Start (context) 116VOID* context; 117{ 118 /* call md specific initialization here */ 119 120 CRC = zf.zcrc32 (0L, Z_NULL, 0); 121} 122 123/* 124 *------------------------------------------------------* 125 * 126 * MDcrcz_Update -- 127 * 128 * ------------------------------------------------* 129 * Update the internal state of the message digest 130 * generator for a single character. 131 * ------------------------------------------------* 132 * 133 * Sideeffects: 134 * As of the called procedure. 135 * 136 * Result: 137 * None. 138 * 139 *------------------------------------------------------* 140 */ 141 142static void 143MDcrcz_Update (context, character) 144VOID* context; 145unsigned int character; 146{ 147 /* call md specific update here */ 148 149 unsigned char buf = character; 150 151 CRC = zf.zcrc32 (CRC, &buf, 1); 152} 153 154/* 155 *------------------------------------------------------* 156 * 157 * MDcrcz_UpdateBuf -- 158 * 159 * ------------------------------------------------* 160 * Update the internal state of the message digest 161 * generator for a character buffer. 162 * ------------------------------------------------* 163 * 164 * Sideeffects: 165 * As of the called procedure. 166 * 167 * Result: 168 * None. 169 * 170 *------------------------------------------------------* 171 */ 172 173static void 174MDcrcz_UpdateBuf (context, buffer, bufLen) 175VOID* context; 176unsigned char* buffer; 177int bufLen; 178{ 179 /* call md specific update here */ 180 181 CRC = zf.zcrc32 (CRC, buffer, bufLen); 182} 183 184/* 185 *------------------------------------------------------* 186 * 187 * MDcrcz_Final -- 188 * 189 * ------------------------------------------------* 190 * Generate the digest from the internal state of 191 * the message digest generator. 192 * ------------------------------------------------* 193 * 194 * Sideeffects: 195 * As of the called procedure. 196 * 197 * Result: 198 * None. 199 * 200 *------------------------------------------------------* 201 */ 202 203static void 204MDcrcz_Final (context, digest) 205VOID* context; 206VOID* digest; 207{ 208 /* call md specific finalization here */ 209 210 uLong crc = CRC; 211 char* out = (char*) digest; 212 213 /* LITTLE ENDIAN output */ 214 out [3] = (char) ((crc >> 24) & 0xff); 215 out [2] = (char) ((crc >> 16) & 0xff); 216 out [1] = (char) ((crc >> 8) & 0xff); 217 out [0] = (char) ((crc >> 0) & 0xff); 218} 219 220/* 221 *------------------------------------------------------* 222 * 223 * MDcrcz_Check -- 224 * 225 * ------------------------------------------------* 226 * Check for existence of libz, load it. 227 * ------------------------------------------------* 228 * 229 * Sideeffects: 230 * As of the called procedure. 231 * 232 * Result: 233 * None. 234 * 235 *------------------------------------------------------* 236 */ 237 238static int 239MDcrcz_Check (interp) 240Tcl_Interp* interp; 241{ 242 return TrfLoadZlib (interp); 243} 244 245