SPVM-Digest-SHA

 view release on metacpan or  search on metacpan

perl_impl/SHA.xs  view on Meta::CPAN

	Digest::SHA::hmac_sha512256_base64 = 20
PREINIT:
	int i;
	UCHR *key = (UCHR *) "";
	UCHR *data;
	STRLEN len = 0;
	HMAC hmac;
	char *result;
CODE:
	if (items > 0) {
		key = (UCHR *) (SvPVbyte(ST(items-1), len));
	}
	if (hmacinit(&hmac, ix2alg[ix], key, (UINT) len) == NULL)
		XSRETURN_UNDEF;
	for (i = 0; i < items - 1; i++) {
		data = (UCHR *) (SvPVbyte(ST(i), len));
		while (len > MAX_WRITE_SIZE) {
			hmacwrite(data, MAX_WRITE_SIZE << 3, &hmac);
			data += MAX_WRITE_SIZE;
			len  -= MAX_WRITE_SIZE;
		}
		hmacwrite(data, (ULNG) len << 3, &hmac);
	}
	hmacfinish(&hmac);
	len = 0;
	if (ix % 3 == 0) {
		result = (char *) hmacdigest(&hmac);
		len = hmac.digestlen;
	}
	else if (ix % 3 == 1)
		result = hmachex(&hmac);
	else
		result = hmacbase64(&hmac);
	RETVAL = newSVpv(result, len);
OUTPUT:
	RETVAL

int
hashsize(self)
	SV *	self
ALIAS:
	Digest::SHA::hashsize = 0
	Digest::SHA::algorithm = 1
PREINIT:
	SHA *state;
CODE:
	if ((state = getSHA(aTHX_ self)) == NULL)
		XSRETURN_UNDEF;
	RETVAL = ix ? state->alg : (int) (state->digestlen << 3);
OUTPUT:
	RETVAL

void
add(self, ...)
	SV *	self
PREINIT:
	int i;
	UCHR *data;
	STRLEN len;
	SHA *state;
PPCODE:
	if ((state = getSHA(aTHX_ self)) == NULL)
		XSRETURN_UNDEF;
	for (i = 1; i < items; i++) {
		data = (UCHR *) (SvPVbyte(ST(i), len));
		while (len > MAX_WRITE_SIZE) {
			shawrite(data, MAX_WRITE_SIZE << 3, state);
			data += MAX_WRITE_SIZE;
			len  -= MAX_WRITE_SIZE;
		}
		shawrite(data, (ULNG) len << 3, state);
	}
	XSRETURN(1);

SV *
digest(self)
	SV *	self
ALIAS:
	Digest::SHA::digest = 0
	Digest::SHA::hexdigest = 1
	Digest::SHA::b64digest = 2
PREINIT:
	STRLEN len;
	SHA *state;
	char *result;
CODE:
	if ((state = getSHA(aTHX_ self)) == NULL)
		XSRETURN_UNDEF;
	shafinish(state);
	len = 0;
	if (ix == 0) {
		result = (char *) shadigest(state);
		len = state->digestlen;
	}
	else if (ix == 1)
		result = shahex(state);
	else
		result = shabase64(state);
	RETVAL = newSVpv(result, len);
	sharewind(state);
OUTPUT:
	RETVAL

SV *
_getstate(self)
	SV *	self
PREINIT:
	SHA *state;
	UCHR buf[256];
	UCHR *ptr = buf;
CODE:
	if ((state = getSHA(aTHX_ self)) == NULL)
		XSRETURN_UNDEF;
	Copy(digcpy(state), ptr, state->alg <= SHA256 ? 32 : 64, UCHR);
	ptr += state->alg <= SHA256 ? 32 : 64;
	Copy(state->block, ptr, state->alg <= SHA256 ? 64 : 128, UCHR);
	ptr += state->alg <= SHA256 ? 64 : 128;
	ptr = w32mem(ptr, state->blockcnt);
	ptr = w32mem(ptr, state->lenhh);
	ptr = w32mem(ptr, state->lenhl);
	ptr = w32mem(ptr, state->lenlh);
	ptr = w32mem(ptr, state->lenll);
	RETVAL = newSVpv((char *) buf, (STRLEN) (ptr - buf));
OUTPUT:
	RETVAL

void
_putstate(self, packed_state)
	SV *	self
	SV *	packed_state
PREINIT:
	UINT bc;
	STRLEN len;
	SHA *state;
	UCHR *data;
PPCODE:
	if ((state = getSHA(aTHX_ self)) == NULL)
		XSRETURN_UNDEF;
	data = (UCHR *) SvPV(packed_state, len);
	if (len != (state->alg <= SHA256 ? 116U : 212U))
		XSRETURN_UNDEF;
	data = statecpy(state, data);
	Copy(data, state->block, state->blocksize >> 3, UCHR);
	data += (state->blocksize >> 3);
	bc = memw32(data), data += 4;
	if (bc >= (state->alg <= SHA256 ? 512U : 1024U))
		XSRETURN_UNDEF;
	state->blockcnt = bc;
	state->lenhh = memw32(data), data += 4;
	state->lenhl = memw32(data), data += 4;
	state->lenlh = memw32(data), data += 4;
	state->lenll = memw32(data);
	XSRETURN(1);

void
_addfilebin(self, f)
	SV *		self
	PerlIO *	f
PREINIT:
	SHA *state;
	int n;
	UCHR in[IO_BUFFER_SIZE];
PPCODE:
	if (!f || (state = getSHA(aTHX_ self)) == NULL)
		XSRETURN_UNDEF;
	while ((n = (int) PerlIO_read(f, in, sizeof(in))) > 0)
		shawrite(in, (ULNG) n << 3, state);
	XSRETURN(1);

void
_addfileuniv(self, f)
	SV *		self
	PerlIO *	f
PREINIT:
	UCHR c;
	int n;
	int cr = 0;
	UCHR *src, *dst;
	UCHR in[IO_BUFFER_SIZE+1];
	SHA *state;
PPCODE:
	if (!f || (state = getSHA(aTHX_ self)) == NULL)
		XSRETURN_UNDEF;
	while ((n = (int) PerlIO_read(f, in+1, IO_BUFFER_SIZE)) > 0) {
		for (dst = in, src = in + 1; n; n--) {
			c = *src++;
			if (!cr) {
				if (c == '\015')
					cr = 1;
				else
					*dst++ = c;
			}
			else {
				if (c == '\015')
					*dst++ = '\012';
				else if (c == '\012') {
					*dst++ = '\012';
					cr = 0;
				}
				else {
					*dst++ = '\012';
					*dst++ = c;
					cr = 0;
				}
			}
		}
		shawrite(in, (ULNG) (dst - in) << 3, state);
	}
	if (cr) {
		in[0] = '\012';
		shawrite(in, 1UL << 3, state);
	}
	XSRETURN(1);



( run in 1.195 second using v1.01-cache-2.11-cpan-5511b514fd6 )