Updating built in Io code to use += instead of x = x + y
[io/quag.git] / addons / SHA1 / source / IoSHA1.c
blob23c7d079724e292a385af68ff6dbc6d8ffe5eab6
1 /*#io
2 SHA1 ioDoc(
3 docCopyright("Steve Dekorte", 2002)
4 docLicense("BSD revised")
5 docDescription("An object for calculating SHA1 hashes. Each has calculation should instiate it's own SHA1 instance.")
6 docCategory("Digests")
7 */
9 #include "IoSHA1.h"
10 #include "IoState.h"
11 #include "IoSeq.h"
13 #define DATA(self) ((IoSHA1Data *)IoObject_dataPointer(self))
15 IoTag *IoSHA1_newTag(void *state)
17 IoTag *tag = IoTag_newWithName_("SHA1");
18 IoTag_state_(tag, state);
19 IoTag_freeFunc_(tag, (IoTagFreeFunc *)IoSHA1_free);
20 IoTag_cloneFunc_(tag, (IoTagCloneFunc *)IoSHA1_rawClone);
21 return tag;
24 IoSHA1 *IoSHA1_proto(void *state)
26 IoObject *self = IoObject_new(state);
27 IoObject_tag_(self, IoSHA1_newTag(state));
29 IoObject_setDataPointer_(self, calloc(1, sizeof(IoSHA1Data)));
30 SHA1Init(&(DATA(self)->context));
32 IoState_registerProtoWithFunc_(state, self, IoSHA1_proto);
35 IoMethodTable methodTable[] = {
36 {"appendSeq", IoSHA1_appendSeq},
37 {"sha1", IoSHA1_sha1},
38 {"sha1String", IoSHA1_sha1String},
39 {NULL, NULL},
41 IoObject_addMethodTable_(self, methodTable);
43 return self;
46 IoSHA1 *IoSHA1_rawClone(IoSHA1 *proto)
48 IoObject *self = IoObject_rawClonePrimitive(proto);
49 IoObject_setDataPointer_(self, calloc(1, sizeof(IoSHA1Data)));
50 SHA1Init(&(DATA(self)->context));
51 return self;
54 IoSHA1 *IoSHA1_new(void *state)
56 IoSHA1 *proto = IoState_protoWithInitFunction_(state, IoSHA1_proto);
57 return IOCLONE(proto);
60 void IoSHA1_free(IoSHA1 *self)
62 free(IoObject_dataPointer(self));
65 /* ----------------------------------------------------------- */
67 IoObject *IoSHA1_appendSeq(IoSHA1 *self, IoObject *locals, IoMessage *m)
69 /*#io
70 docSlot("appendSeq(aSequence)",
71 "Appends aSequence to the hash calculation. Returns self.")
74 IoSeq *buffer = IoMessage_locals_seqArgAt_(m, locals, 0);
75 IOASSERT(DATA(self)->isDone == 0, "cannot append to an already calculated sha1");
76 SHA1Update(&(DATA(self)->context),
77 (unsigned char const *)IoSeq_rawBytes(buffer),
78 IoSeq_rawSize(buffer));
79 return self;
82 UArray *IoSHA1_sha1UArray(IoSHA1 *self)
84 if (DATA(self)->isDone == 0)
86 SHA1Final(DATA(self)->digest, &(DATA(self)->context));
87 DATA(self)->isDone = 1;
90 return UArray_newWithData_type_size_copy_(DATA(self)->digest, CTYPE_uint8_t, SHA1_DIGEST_LENGTH, 1);
93 IoObject *IoSHA1_sha1(IoSHA1 *self, IoObject *locals, IoMessage *m)
95 /*#io
96 docSlot("sha1",
97 "Completes the SHA1 calculation and returns the hash as a Buffer.
98 Once this method is called, append() should not be called again on the receiver or it will raise an exception.")
100 return IoSeq_newWithUArray_copy_(IOSTATE, IoSHA1_sha1UArray(self), 0);
103 IoObject *IoSHA1_sha1String(IoSHA1 *self, IoObject *locals, IoMessage *m)
105 /*#io
106 docSlot("sha1String", " description: Returns a string containing a hexadecimal representation of the sha1 hash.")
108 UArray *ba = IoSHA1_sha1UArray(self);
109 UArray *baString = UArray_asNewHexStringUArray(ba);
110 UArray_free(ba);
111 return IoState_symbolWithUArray_copy_(IOSTATE, baString, 0);