28
28
static const unsigned char itoa64f [] =
29
29
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_," ;
30
30
31
- #define DIGESTSIZE 20
31
+ static int numcontexts = 0 ;
32
+ static SHA1_CTX * sha1Contexts = NULL ;
33
+ static Tcl_Size * ctxtotalRead = NULL ;
32
34
33
- /*
34
- * The procedure needs interpreter local state. This is called
35
- * "Command client data" in TCL. Typically, a struct is allocated and
36
- * the pointer to it is made available on each operation by TCL.
37
- * Here is the struct for the sha1 procedure.
38
- */
35
+ static int Sha1_Cmd (void * clientData , Tcl_Interp * interp ,
36
+ int objc , Tcl_Obj * const objv []);
39
37
40
- struct Sha1ClientData {
41
- int numcontexts ;
42
- SHA1_CTX * sha1Contexts ;
43
- Tcl_Size * ctxtotalRead ;
44
- };
38
+ #define DIGESTSIZE 20
45
39
46
40
/*
47
41
* The DLL needs interpreter local storage to get the command tolkens to the
@@ -81,18 +75,12 @@ struct DllAssocData {
81
75
82
76
static int
83
77
Sha1_Cmd (
84
- ClientData clientData , /* Client data with thread local state */
78
+ void * dummy , /* Not used. */
85
79
Tcl_Interp * interp , /* Current interpreter */
86
80
int objc , /* Number of arguments */
87
81
Tcl_Obj * const objv [] /* Argument strings */
88
82
)
89
83
{
90
- /*
91
- * Get my thread local memory
92
- */
93
-
94
- struct Sha1ClientData * sha1ClientDataPtr = clientData ;
95
-
96
84
/*
97
85
* The default base is hex
98
86
*/
@@ -104,13 +92,15 @@ Sha1_Cmd(
104
92
Tcl_Channel copychan = NULL ;
105
93
int mode ;
106
94
int contextnum = 0 ;
95
+ #define sha1Context (sha1Contexts[contextnum])
107
96
char * bufPtr ;
108
97
Tcl_WideInt maxbytes = 0 ;
109
98
int doinit = 1 ;
110
99
int dofinal = 1 ;
111
100
Tcl_Obj * descriptorObj = NULL ;
112
101
Tcl_Size totalRead = 0 , n ;
113
102
int i , j , mask , bits , offset ;
103
+ (void )dummy ;
114
104
115
105
/*
116
106
* For binary representation + null char
@@ -143,26 +133,24 @@ Sha1_Cmd(
143
133
}
144
134
switch ((enum ShaOpts ) index ) {
145
135
case SHAOPT_INIT :
146
- for (contextnum = 1 ; contextnum < sha1ClientDataPtr -> numcontexts ; contextnum ++ ) {
147
- if (sha1ClientDataPtr -> ctxtotalRead [contextnum ] == -1 ) {
136
+ for (contextnum = 1 ; contextnum < numcontexts ; contextnum ++ ) {
137
+ if (ctxtotalRead [contextnum ] == -1 ) {
148
138
break ;
149
139
}
150
140
}
151
- if (contextnum == sha1ClientDataPtr -> numcontexts ) {
141
+ if (contextnum == numcontexts ) {
152
142
/*
153
143
* Allocate a new context.
154
144
*/
155
145
156
- sha1ClientDataPtr -> numcontexts ++ ;
157
- sha1ClientDataPtr -> sha1Contexts = (SHA1_CTX * ) ckrealloc (
158
- (void * ) sha1ClientDataPtr -> sha1Contexts ,
159
- sha1ClientDataPtr -> numcontexts * sizeof (SHA1_CTX ));
160
- sha1ClientDataPtr -> ctxtotalRead = (Tcl_Size * )ckrealloc (
161
- sha1ClientDataPtr -> ctxtotalRead ,
162
- sha1ClientDataPtr -> numcontexts * sizeof (Tcl_Size ));
146
+ numcontexts ++ ;
147
+ sha1Contexts = (SHA1_CTX * ) ckrealloc ((void * ) sha1Contexts ,
148
+ numcontexts * sizeof (SHA1_CTX ));
149
+ ctxtotalRead = (Tcl_Size * )ckrealloc (ctxtotalRead ,
150
+ numcontexts * sizeof (Tcl_Size ));
163
151
}
164
- sha1ClientDataPtr -> ctxtotalRead [contextnum ] = 0 ;
165
- SHA1Init (& sha1ClientDataPtr -> sha1Contexts [ contextnum ] );
152
+ ctxtotalRead [contextnum ] = 0 ;
153
+ SHA1Init (& sha1Context );
166
154
snprintf (buf , sizeof (buf ), "sha1%d" , contextnum );
167
155
Tcl_AppendResult (interp , buf , NULL );
168
156
return TCL_OK ;
@@ -220,16 +208,16 @@ Sha1_Cmd(
220
208
221
209
if (descriptorObj != NULL ) {
222
210
if ((sscanf (Tcl_GetString (descriptorObj ), "sha1%d" ,
223
- & contextnum ) != 1 ) || (contextnum >= sha1ClientDataPtr -> numcontexts ) ||
224
- (sha1ClientDataPtr -> ctxtotalRead [contextnum ] == -1 )) {
211
+ & contextnum ) != 1 ) || (contextnum >= numcontexts ) ||
212
+ (ctxtotalRead [contextnum ] == -1 )) {
225
213
Tcl_AppendResult (interp , "invalid sha1 descriptor \"" ,
226
214
Tcl_GetString (descriptorObj ), "\"" , NULL );
227
215
return TCL_ERROR ;
228
216
}
229
217
}
230
218
231
219
if (doinit ) {
232
- SHA1Init (& sha1ClientDataPtr -> sha1Contexts [ contextnum ] );
220
+ SHA1Init (& sha1Context );
233
221
}
234
222
235
223
if (stringObj != NULL ) {
@@ -238,17 +226,10 @@ Sha1_Cmd(
238
226
goto wrongArgs ;
239
227
}
240
228
string = Tcl_GetStringFromObj (stringObj , & totalRead );
241
- SHA1Update (& sha1ClientDataPtr -> sha1Contexts [contextnum ],
242
- (unsigned char * ) string , totalRead );
229
+ SHA1Update (& sha1Context , (unsigned char * ) string , totalRead );
243
230
} else if (chan != NULL ) {
244
231
bufPtr = (char * )ckalloc (TCL_READ_CHUNK_SIZE );
245
232
totalRead = 0 ;
246
- /*
247
- * FIXME: MS-VC 2015 gives the following warning in the next line I
248
- * was not able to fix (translated from German):
249
- * warning C4244: "Function": Conversion of "Tcl_WideInt" to "int",
250
- * possible data loss
251
- */
252
233
while ((n = Tcl_Read (chan , bufPtr ,
253
234
maxbytes == 0
254
235
? TCL_READ_CHUNK_SIZE
@@ -265,8 +246,7 @@ Sha1_Cmd(
265
246
266
247
totalRead += n ;
267
248
268
- SHA1Update (& sha1ClientDataPtr -> sha1Contexts [contextnum ],
269
- (unsigned char * ) bufPtr , n );
249
+ SHA1Update (& sha1Context , (unsigned char * ) bufPtr , n );
270
250
271
251
if (copychan != NULL ) {
272
252
n = Tcl_Write (copychan , bufPtr , n );
@@ -290,17 +270,17 @@ Sha1_Cmd(
290
270
}
291
271
292
272
if (!dofinal ) {
293
- sha1ClientDataPtr -> ctxtotalRead [contextnum ] += totalRead ;
273
+ ctxtotalRead [contextnum ] += totalRead ;
294
274
Tcl_SetObjResult (interp , Tcl_NewWideIntObj (totalRead ));
295
275
return TCL_OK ;
296
276
}
297
277
298
278
if (stringObj == NULL ) {
299
- totalRead += sha1ClientDataPtr -> ctxtotalRead [contextnum ];
279
+ totalRead += ctxtotalRead [contextnum ];
300
280
Tcl_SetObjResult (interp , Tcl_NewWideIntObj (totalRead ));
301
281
}
302
282
303
- SHA1Final (& sha1ClientDataPtr -> sha1Contexts [ contextnum ] , digest );
283
+ SHA1Final (& sha1Context , digest );
304
284
305
285
/*
306
286
* Take the 20 byte array and print it in the requested base
@@ -337,7 +317,7 @@ Sha1_Cmd(
337
317
buf [j ++ ] = '\0' ;
338
318
Tcl_AppendResult (interp , buf , NULL );
339
319
if (contextnum > 0 ) {
340
- sha1ClientDataPtr -> ctxtotalRead [contextnum ] = -1 ;
320
+ ctxtotalRead [contextnum ] = -1 ;
341
321
}
342
322
return TCL_OK ;
343
323
@@ -366,42 +346,6 @@ Sha1_Cmd(
366
346
return TCL_ERROR ;
367
347
}
368
348
369
-
370
- /*
371
- *----------------------------------------------------------------------
372
- *
373
- * Sha1_CmdDeleteProc --
374
- *
375
- * Clear all thread data of the Sha1 command.
376
- *
377
- * Results:
378
- * No result
379
- *
380
- * Side effects:
381
- * None.
382
- *
383
- *----------------------------------------------------------------------
384
- */
385
-
386
- static void
387
- Sha1_CmdDeleteProc (ClientData clientData )
388
- {
389
- struct Sha1ClientData * sha1ClientDataPtr = clientData ;
390
-
391
- /*
392
- * Release the sha1 contextes
393
- */
394
-
395
- ckfree (sha1ClientDataPtr -> sha1Contexts );
396
- ckfree (sha1ClientDataPtr -> ctxtotalRead );
397
-
398
- /*
399
- * Release the procedure client data
400
- */
401
-
402
- ckfree (sha1ClientDataPtr );
403
- }
404
-
405
349
406
350
/*
407
351
*----------------------------------------------------------------------
@@ -496,7 +440,6 @@ Sample_Init(
496
440
{
497
441
Tcl_CmdInfo info ;
498
442
struct DllAssocData * dllAssocDataPtr ;
499
- struct Sha1ClientData * sha1ClientDataPtr ;
500
443
501
444
/*
502
445
* Require compatible TCL version.
@@ -519,26 +462,6 @@ Sample_Init(
519
462
dllAssocDataPtr = ckalloc (sizeof (struct DllAssocData ));
520
463
Tcl_SetAssocData (interp , ASSOC_DATA_KEY , pkgInterpDeleted , dllAssocDataPtr );
521
464
522
- /*
523
- * Init the sha1 context queues
524
- */
525
-
526
- sha1ClientDataPtr = ckalloc (sizeof (struct Sha1ClientData ));
527
- sha1ClientDataPtr -> numcontexts = 1 ;
528
- sha1ClientDataPtr -> sha1Contexts = (SHA1_CTX * ) ckalloc (sizeof (SHA1_CTX ));
529
- sha1ClientDataPtr -> ctxtotalRead = (Tcl_Size * ) ckalloc (sizeof (Tcl_Size ));
530
-
531
- /*
532
- * Create the sha1 command.
533
- * Pass the client data pointer to the procedure, so the queue data is
534
- * available.
535
- * Also, register a delete proc to clear the sha1 queue on deletion.
536
- */
537
-
538
- dllAssocDataPtr -> sha1CmdTolken = Tcl_CreateObjCommand (
539
- interp , "sha1" , (Tcl_ObjCmdProc * )Sha1_Cmd ,
540
- sha1ClientDataPtr , Sha1_CmdDeleteProc );
541
-
542
465
/*
543
466
* Create the buildinfo command if tcl supports it
544
467
*/
@@ -608,12 +531,19 @@ Sample_Init(
608
531
609
532
dllAssocDataPtr -> buildInfoCmdTolken = NULL ;
610
533
}
611
-
534
+
612
535
/* Provide the current package */
613
536
614
537
if (Tcl_PkgProvideEx (interp , PACKAGE_NAME , PACKAGE_VERSION , NULL ) != TCL_OK ) {
615
538
return TCL_ERROR ;
616
539
}
540
+ dllAssocDataPtr -> sha1CmdTolken = Tcl_CreateObjCommand (interp , "sha1" , (Tcl_ObjCmdProc * )Sha1_Cmd ,
541
+ NULL , NULL );
542
+
543
+ numcontexts = 1 ;
544
+ sha1Contexts = (SHA1_CTX * ) ckalloc (sizeof (SHA1_CTX ));
545
+ ctxtotalRead = (Tcl_Size * ) ckalloc (sizeof (Tcl_Size ));
546
+ ctxtotalRead [0 ] = 0 ;
617
547
618
548
return TCL_OK ;
619
549
}
0 commit comments