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