1/* 2 * adler.c -- 3 * 4 * Implements and registers message digest generator ADLER32. 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: adler.c,v 1.8 2003/01/09 21:27:09 andreas_kupries Exp $ 28 */ 29 30#include "transformInt.h" 31 32/* 33 * Generator description 34 * --------------------- 35 * 36 * The ADLER32 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 MDAdler_Start _ANSI_ARGS_ ((VOID* context)); 48static void MDAdler_Update _ANSI_ARGS_ ((VOID* context, unsigned int character)); 49static void MDAdler_UpdateBuf _ANSI_ARGS_ ((VOID* context, unsigned char* buffer, int bufLen)); 50static void MDAdler_Final _ANSI_ARGS_ ((VOID* context, VOID* digest)); 51static int MDAdler_Check _ANSI_ARGS_ ((Tcl_Interp* interp)); 52 53/* 54 * Generator definition. 55 */ 56 57static Trf_MessageDigestDescription mdDescription = { /* THREADING: constant, read-only => safe */ 58 "adler", 59 sizeof (CTX_TYPE), 60 DIGEST_SIZE, 61 MDAdler_Start, 62 MDAdler_Update, 63 MDAdler_UpdateBuf, 64 MDAdler_Final, 65 MDAdler_Check 66}; 67 68#define ADLER (*((uLong*) context)) 69 70/* 71 *------------------------------------------------------* 72 * 73 * TrfInit_ADLER -- 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_ADLER (interp) 90Tcl_Interp* interp; 91{ 92 return Trf_RegisterMessageDigest (interp, &mdDescription); 93} 94 95/* 96 *------------------------------------------------------* 97 * 98 * MDAdler_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 115MDAdler_Start (context) 116VOID* context; 117{ 118 START (MDAdler_Start); 119 PRINT ("Context = %p, Zf = %p\n", context, &zf); 120 121 /* call md specific initialization here */ 122 123 ADLER = zf.zadler32 (0L, Z_NULL, 0); 124 125 DONE (MDAdler_Start); 126} 127 128/* 129 *------------------------------------------------------* 130 * 131 * MDAdler_Update -- 132 * 133 * ------------------------------------------------* 134 * Update the internal state of the message digest 135 * generator for a single character. 136 * ------------------------------------------------* 137 * 138 * Sideeffects: 139 * As of the called procedure. 140 * 141 * Result: 142 * None. 143 * 144 *------------------------------------------------------* 145 */ 146 147static void 148MDAdler_Update (context, character) 149VOID* context; 150unsigned int character; 151{ 152 /* call md specific update here */ 153 154 unsigned char buf = character; 155 156 ADLER = zf.zadler32 (ADLER, &buf, 1); 157} 158 159/* 160 *------------------------------------------------------* 161 * 162 * MDAdler_UpdateBuf -- 163 * 164 * ------------------------------------------------* 165 * Update the internal state of the message digest 166 * generator for a character buffer. 167 * ------------------------------------------------* 168 * 169 * Sideeffects: 170 * As of the called procedure. 171 * 172 * Result: 173 * None. 174 * 175 *------------------------------------------------------* 176 */ 177 178static void 179MDAdler_UpdateBuf (context, buffer, bufLen) 180VOID* context; 181unsigned char* buffer; 182int bufLen; 183{ 184 /* call md specific update here */ 185 186 ADLER = zf.zadler32 (ADLER, buffer, bufLen); 187} 188 189/* 190 *------------------------------------------------------* 191 * 192 * MDAdler_Final -- 193 * 194 * ------------------------------------------------* 195 * Generate the digest from the internal state of 196 * the message digest generator. 197 * ------------------------------------------------* 198 * 199 * Sideeffects: 200 * As of the called procedure. 201 * 202 * Result: 203 * None. 204 * 205 *------------------------------------------------------* 206 */ 207 208static void 209MDAdler_Final (context, digest) 210VOID* context; 211VOID* digest; 212{ 213 /* call md specific finalization here */ 214 215 uLong adler = ADLER; 216 char* out = (char*) digest; 217 218 /* BIGENDIAN output */ 219 out [0] = (char) ((adler >> 24) & 0xff); 220 out [1] = (char) ((adler >> 16) & 0xff); 221 out [2] = (char) ((adler >> 8) & 0xff); 222 out [3] = (char) ((adler >> 0) & 0xff); 223} 224 225/* 226 *------------------------------------------------------* 227 * 228 * MDAdler_Check -- 229 * 230 * ------------------------------------------------* 231 * Check for existence of libz, load it. 232 * ------------------------------------------------* 233 * 234 * Sideeffects: 235 * As of the called procedure. 236 * 237 * Result: 238 * None. 239 * 240 *------------------------------------------------------* 241 */ 242 243static int 244MDAdler_Check (interp) 245Tcl_Interp* interp; 246{ 247 int res; 248 249 START (MDAdler_Check); 250 251 res = TrfLoadZlib (interp); 252 253 PRINT ("res = %d\n", res); 254 DONE (MDAdler_Check); 255 return res; 256} 257 258