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