Sync up with Digest-MD5-2.38 from CPAN
[p5sagit/p5-mst-13.2.git] / ext / Digest / MD5 / MD5.xs
index 287550c..a743b05 100644 (file)
@@ -1,5 +1,3 @@
-/* $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.
@@ -37,6 +35,7 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+#define PERL_NO_GET_CONTEXT     /* we want efficiency */
 #include "EXTERN.h"
 #include "perl.h"
 #include "XSUB.h"
@@ -83,6 +82,11 @@ extern "C" {
    #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
@@ -147,7 +151,7 @@ typedef struct {
  * 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
@@ -460,7 +464,7 @@ MD5Final(U8* digest, MD5_CTX *ctx)
 #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);
@@ -478,7 +482,7 @@ static MD5_CTX* get_md5_ctx(SV* 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;
 
@@ -493,7 +497,7 @@ static char* hex_16(const unsigned char* from, char* 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;
@@ -521,7 +525,7 @@ static char* base64_16(const unsigned char* from, char* to)
 #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];
@@ -571,7 +575,7 @@ new(xclass)
            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);
@@ -580,11 +584,10 @@ void
 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);
@@ -602,7 +605,7 @@ void
 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;
@@ -618,12 +621,20 @@ addfile(self, fh)
        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
@@ -640,7 +651,9 @@ addfile(self, fh)
             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");
            }
@@ -662,7 +675,7 @@ digest(context)
     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
@@ -696,10 +709,15 @@ md5(...)
                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);
            }
        }
@@ -709,5 +727,5 @@ md5(...)
            MD5Update(&ctx, data, len);
        }
        MD5Final(digeststr, &ctx);
-        ST(0) = make_mortal_sv(digeststr, ix);
+        ST(0) = make_mortal_sv(aTHX_ digeststr, ix);
         XSRETURN(1);