-/* $Id: MD5.xs,v 1.40 2003/07/22 05:59:27 gisle Exp $ */
-
/*
* This library is free software; you can redistribute it and/or
* modify it under the same terms as Perl itself.
#ifdef __cplusplus
extern "C" {
#endif
+#define PERL_NO_GET_CONTEXT /* we want efficiency */
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#define SvPVbyte SvPV
#endif
+#ifndef dTHX
+ #define pTHX_
+ #define aTHX_
+#endif
+
/* Perl does not guarantee that U32 is exactly 32 bits. Some system
* has no integral type with exactly 32 bits. For instance, A Cray has
* short, int and long all at 64 bits so we need to apply this macro
* padding is also the reason the buffer in MD5_CTX have to be
* 128 bytes.
*/
-static unsigned char PADDING[64] = {
+static const unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
#define INT2PTR(any,d) (any)(d)
#endif
-static MD5_CTX* get_md5_ctx(SV* sv)
+static MD5_CTX* get_md5_ctx(pTHX_ SV* sv)
{
if (SvROK(sv)) {
sv = SvRV(sv);
static char* hex_16(const unsigned char* from, char* to)
{
- static char *hexdigits = "0123456789abcdef";
+ static const char hexdigits[] = "0123456789abcdef";
const unsigned char *end = from + 16;
char *d = to;
static char* base64_16(const unsigned char* from, char* to)
{
- static char* base64 =
+ static const char base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const unsigned char *end = from + 16;
unsigned char c1, c2, c3;
#define F_HEX 1
#define F_B64 2
-static SV* make_mortal_sv(const unsigned char *src, int type)
+static SV* make_mortal_sv(pTHX_ const unsigned char *src, int type)
{
STRLEN len;
char result[33];
sv_setref_pv(ST(0), sclass, (void*)context);
SvREADONLY_on(SvRV(ST(0)));
} else {
- context = get_md5_ctx(xclass);
+ context = get_md5_ctx(aTHX_ xclass);
}
MD5Init(context);
XSRETURN(1);
clone(self)
SV* self
PREINIT:
- MD5_CTX* cont = get_md5_ctx(self);
- char *myname = sv_reftype(SvRV(self),TRUE);
+ MD5_CTX* cont = get_md5_ctx(aTHX_ self);
+ const char *myname = sv_reftype(SvRV(self),TRUE);
MD5_CTX* context;
PPCODE:
- STRLEN my_na;
New(55, context, 1, MD5_CTX);
ST(0) = sv_newmortal();
sv_setref_pv(ST(0), myname , (void*)context);
add(self, ...)
SV* self
PREINIT:
- MD5_CTX* context = get_md5_ctx(self);
+ MD5_CTX* context = get_md5_ctx(aTHX_ self);
int i;
unsigned char *data;
STRLEN len;
SV* self
InputStream fh
PREINIT:
- MD5_CTX* context = get_md5_ctx(self);
+ MD5_CTX* context = get_md5_ctx(aTHX_ self);
STRLEN fill = context->bytes_low & 0x3F;
+#ifdef USE_HEAP_INSTEAD_OF_STACK
+ unsigned char* buffer;
+#else
unsigned char buffer[4096];
+#endif
int n;
CODE:
if (fh) {
+#ifdef USE_HEAP_INSTEAD_OF_STACK
+ New(0, buffer, 4096, unsigned char);
+ assert(buffer);
+#endif
if (fill) {
/* The MD5Update() function is faster if it can work with
* complete blocks. This will fill up any buffered block
while ( (n = PerlIO_read(fh, buffer, sizeof(buffer))) > 0) {
MD5Update(context, buffer, n);
}
-
+#ifdef USE_HEAP_INSTEAD_OF_STACK
+ Safefree(buffer);
+#endif
if (PerlIO_error(fh)) {
croak("Reading from filehandle failed");
}
PPCODE:
MD5Final(digeststr, context);
MD5Init(context); /* In case it is reused */
- ST(0) = make_mortal_sv(digeststr, ix);
+ ST(0) = make_mortal_sv(aTHX_ digeststr, ix);
XSRETURN(1);
void
if (len == 11 && memEQ("Digest::MD5", data, 11)) {
msg = "probably called as class method";
}
+ else if (SvROK(ST(0))) {
+ SV* sv = SvRV(ST(0));
+ if (SvOBJECT(sv) && strEQ(HvNAME(SvSTASH(sv)), "Digest::MD5"))
+ msg = "probably called as method";
+ }
}
if (msg) {
- char *f = (ix == F_BIN) ? "md5" :
- (ix == F_HEX) ? "md5_hex" : "md5_base64";
+ const char *f = (ix == F_BIN) ? "md5" :
+ (ix == F_HEX) ? "md5_hex" : "md5_base64";
warn("&Digest::MD5::%s function %s", f, msg);
}
}
MD5Update(&ctx, data, len);
}
MD5Final(digeststr, &ctx);
- ST(0) = make_mortal_sv(digeststr, ix);
+ ST(0) = make_mortal_sv(aTHX_ digeststr, ix);
XSRETURN(1);