Update date
[filehash.git] / src / hash.c
blob7cdf4fbbc878ff7f4fa2c826557f9c3437744e41
1 #include <R.h>
2 #include <Rinternals.h>
3 #include "sha1.h"
5 /*
6 * This code is adapted from the 'digest.c' code in the 'digest'
7 * package by Dirk Eddelbuettel <edd@debian.org> with contributions by
8 * Antoine Lucas, Jarek Tuszynski, Henrik Bengtsson and Simon Urbanek
9 */
11 SEXP sha1_object(SEXP object, SEXP skip_bytes)
13 char output[41]; /* SHA-1 is 40 bytes + '\0' */
14 int i, skip;
15 SEXP result;
16 sha1_context ctx;
17 unsigned char buffer[20];
18 Rbyte *data;
19 int nChar = length(object);
21 PROTECT(object = coerceVector(object, RAWSXP));
22 data = RAW(object);
23 PROTECT(skip_bytes = coerceVector(skip_bytes, INTSXP));
24 skip = INTEGER(skip_bytes)[0];
26 if(skip > 0) {
27 if(skip >= nChar)
28 nChar = 0;
29 else {
30 nChar -= skip;
31 data += skip;
34 sha1_starts(&ctx);
35 sha1_update(&ctx, (uint8 *) data, nChar);
36 sha1_finish(&ctx, buffer);
38 for(i=0; i < 20; i++)
39 sprintf(output + i * 2, "%02x", buffer[i]);
41 PROTECT(result = allocVector(STRSXP, 1));
42 SET_STRING_ELT(result, 0, mkChar(output));
43 UNPROTECT(3);
45 return result;
49 SEXP sha1_file(SEXP filename, SEXP skip_bytes)
51 char output[41]; /* SHA-1 is 40 bytes + '\0' */
52 int nChar, i, skip;
53 FILE *fp;
54 SEXP result;
55 sha1_context ctx;
56 unsigned char buf[1024];
57 unsigned char sha1sum[20];
59 PROTECT(skip_bytes = coerceVector(skip_bytes, INTSXP));
60 PROTECT(filename = coerceVector(filename, STRSXP));
62 skip = INTEGER(skip_bytes)[0];
64 if(!(fp = fopen(CHAR(STRING_ELT(filename, 0)), "rb")))
65 error("unable to open input file");
66 if (skip > 0)
67 fseek(fp, skip, SEEK_SET);
68 sha1_starts(&ctx);
70 while((nChar = fread(buf, 1, sizeof(buf), fp)) > 0)
71 sha1_update(&ctx, buf, nChar);
73 fclose(fp);
74 sha1_finish(&ctx, sha1sum);
76 for(i=0; i < 20; i++)
77 sprintf(output + i * 2, "%02x", sha1sum[i]);
79 PROTECT(result = allocVector(STRSXP, 1));
80 SET_STRING_ELT(result, 0, mkChar(output));
81 UNPROTECT(3);
83 return result;