1 2 #include "EXTERN.h" 3 #include "perl.h" 4 #include "XSUB.h" 5 6 7 #define BUFFER_SIZE (8192) 8 #define BUFFER_2SIZE (BUFFER_SIZE*2) 9 10 11 typedef unsigned long t_myInt; 12 13 typedef struct ts_Data 14 { 15 t_myInt mask, 16 prime, 17 maskbits, 18 charcount, 19 modulo; 20 21 t_myInt values[256]; 22 } t_Data; 23 24 25 26 MODULE = Digest::ManberHash PACKAGE = Digest::ManberHash 27 28 29 SV* 30 Init(maskbits,prime, charcount) 31 unsigned long maskbits 32 unsigned long prime 33 unsigned long charcount; 34 CODE: 35 { 36 t_Data *data; 37 int i; 38 t_myInt p; 39 40 RETVAL=newSVpvf("%*s",sizeof(*data),"a"); 41 // SvGROW(RETVAL,sizeof(*data)); 42 43 data=(t_Data*)SvPV_nolen(RETVAL); 44 45 data->maskbits=maskbits; 46 data->prime=prime; 47 data->charcount=charcount; 48 data->modulo=-1; 49 data->mask= ~(-1 << maskbits); 50 51 52 for(p=1,i=0; i<data->charcount; i++) 53 p=(p * data->prime) & data->modulo; 54 55 for(i=0; i<256; i++) 56 data->values[i]=(i*p) & data->modulo; 57 58 } 59 OUTPUT: 60 RETVAL 61 62 63 int 64 ManberHash(set, filename, output) 65 char *set 66 char *filename 67 SV *output 68 CODE: 69 { 70 int fh; 71 t_myInt curr,last,prev; 72 char buffer[BUFFER_2SIZE]; 73 int i,b2d,b2use,i_last,count,j; 74 HV * hv; 75 HE * he; 76 SV *sv,**svp; 77 t_Data *settings; 78 char hex[11]; 79 80 RETVAL=0; 81 if (SvTYPE(SvRV(output)) != SVt_PVHV) 82 return; 83 /* if (SvTYPE(SvRV(set)) != SVt_PV) 84 return; 85 settings=(t_Data*)SVPV_nolen(SvRV(set)); 86 */ 87 settings=(t_Data*)set; 88 memset(hex,0,sizeof(hex)); 89 90 91 /* 92 if (strcmp(fn,"-")==0) 93 { 94 fp=stdin; 95 } 96 else 97 { 98 fp=fopen(fn,"rb"); 99 if (fp == NULL) 100 { 101 fprintf(stderr,"Can't open '%s': %s (%d)\n", 102 fn,strerror(errno),errno); 103 exit(1); 104 } 105 } 106 */ 107 108 fh=open(filename,O_RDONLY); 109 if (fh<0) 110 return; 111 112 // printf("file opend\n"); 113 114 b2d=read(fh,buffer,BUFFER_2SIZE); 115 b2use=0; 116 117 if (b2d < settings->charcount) 118 return; 119 120 for(i=curr=0; i<settings->charcount; i++) 121 { 122 curr=curr*settings->prime + buffer[i]; 123 } 124 last=prev=curr; 125 i_last=0; 126 b2d-=settings->charcount; 127 128 hv=(HV*)SvRV(output); 129 130 while (b2d>=0) 131 { 132 if (b2d == BUFFER_SIZE) 133 { 134 b2d += read(fh,buffer + (b2use ? BUFFER_SIZE : 0),BUFFER_SIZE); 135 b2use = !b2use; 136 } 137 138 curr= ( curr * settings->prime + 139 buffer[i] - 140 settings->values[buffer[i_last]] ) 141 & settings->modulo; 142 143 144 if (curr != last) 145 { 146 if ((curr & settings->mask) == 0) 147 { 148 sprintf(hex,"0x%08X",prev); 149 //printf("found hash %08X\n",curr); 150 // hash=curr >> settings->maskbits; 151 svp=hv_fetch(hv, hex, sizeof(hex)-1, 1); 152 if (!svp) return; 153 sv=*svp; 154 if (SvIOK(sv)) 155 count=SvIV(sv)+1; 156 else 157 count=1; 158 159 sv_setiv(sv,count); 160 161 last=curr; 162 } 163 prev=curr; 164 } 165 166 167 i=(i+1) % BUFFER_2SIZE; 168 i_last=(i_last+1) % BUFFER_2SIZE; 169 b2d--; 170 } 171 172 close(fh); 173 174 // printf("finished hashing\n"); 175 176 // XPUSHs( sv_2mortal(newRV_noinc((SV*)hv))); 177 RETVAL=1; 178 } 179 OUTPUT: 180 RETVAL 181 182 183