cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | |
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | ||| This file a part of Pike, and is copyright by Fredrik Hubinette
||| Pike is distributed as GPL (General Public License)
|
cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | ||| See the files COPYING and DISCLAIMER for more information.
\*/
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "global.h"
#include "memory.h"
#include "error.h"
|
bb55f8 | 1997-03-16 | Fredrik Hübinette (Hubbe) | | #include "pike_macros.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
char *xalloc(SIZE_T size)
{
char *ret;
if(!size) return 0;
ret=(char *)malloc(size);
if(ret) return ret;
error("Out of memory.\n");
return 0;
}
|
36feac | 1997-03-06 | Fredrik Hübinette (Hubbe) | | void swap(char *a, char *b, INT32 size)
{
int tmp;
char tmpbuf[1024];
while(size)
{
tmp=MINIMUM((long)sizeof(tmpbuf), size);
MEMCPY(tmpbuf,a,tmp);
MEMCPY(b,a,tmp);
MEMCPY(b,tmpbuf,tmp);
size-=tmp;
a+=tmp;
b+=tmp;
}
}
void reverse(char *memory, INT32 nitems, INT32 size)
{
#define DOSIZE(X,Y) \
case X: \
{ \
struct Y { char tt[X]; }; \
struct Y tmp; \
struct Y *start=(struct Y *) memory; \
struct Y *end=start+nitems-1; \
while(start<end){tmp=*start;*(start++)=*end;*(end--)=tmp;} \
break; \
}
switch(size)
{
DOSIZE(1,TMP1)
DOSIZE(2,TMP2)
DOSIZE(4,TMP4)
DOSIZE(8,TMP8)
default:
{
char *start = (char *) memory;
char *end=start+(nitems-1)*size;
while(start<end)
{
swap(start,end,size);
start+=size;
end-=size;
}
}
}
}
|
b0ddc5 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
void reorder(char *memory, INT32 nitems, INT32 size,INT32 *order)
{
INT32 e;
char *tmp;
tmp=xalloc(size * nitems);
|
36feac | 1997-03-06 | Fredrik Hübinette (Hubbe) | | #undef DOSIZE
|
b0ddc5 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | #define DOSIZE(X,Y) \
case X: \
{ \
struct Y { char tt[X]; }; \
struct Y *from=(struct Y *) memory; \
struct Y *to=(struct Y *) tmp; \
for(e=0;e<nitems;e++) to[e]=from[order[e]]; \
break; \
}
switch(size)
{
DOSIZE(1,TMP1)
DOSIZE(2,TMP2)
DOSIZE(4,TMP4)
DOSIZE(8,TMP8)
DOSIZE(16,TMP16)
default:
for(e=0;e<nitems;e++) MEMCPY(tmp+e*size, memory+order[e]*size, size);
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
b0ddc5 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | MEMCPY(memory, tmp, size * nitems);
free(tmp);
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
unsigned INT32 hashmem(const unsigned char *a,INT32 len,INT32 mlen)
{
unsigned INT32 ret;
ret=9248339*len;
if(len<mlen) mlen=len;
switch(mlen&7)
{
case 7: ret^=*(a++);
case 6: ret^=(ret<<4)+*(a++);
case 5: ret^=(ret<<7)+*(a++);
case 4: ret^=(ret<<6)+*(a++);
case 3: ret^=(ret<<3)+*(a++);
case 2: ret^=(ret<<7)+*(a++);
case 1: ret^=(ret<<5)+*(a++);
}
#ifdef HANDLES_UNALIGNED_MEMORY_ACCESS
{
|
cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | unsigned int *b;
b=(unsigned int *)a;
for(mlen>>=3;--mlen>=0;)
{
ret^=(ret<<7)+*(b++);
ret^=(ret>>6)+*(b++);
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
#else
for(mlen>>=3;--mlen>=0;)
{
ret^=(ret<<7)+((((((*(a++)<<3)+*(a++))<<4)+*(a++))<<5)+*(a++));
ret^=(ret>>6)+((((((*(a++)<<3)+*(a++))<<4)+*(a++))<<5)+*(a++));
}
#endif
return ret;
}
unsigned INT32 hashstr(const unsigned char *str,INT32 maxn)
{
unsigned INT32 ret,c;
ret=str++[0];
for(; maxn>=0; maxn--)
{
c=str++[0];
if(!c) break;
ret ^= ( ret << 4 ) + c ;
ret &= 0x7fffffff;
}
return ret;
}
|
b0ddc5 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
void init_memsearch(struct mem_searcher *s,
char *needle,
SIZE_T needlelen,
SIZE_T max_haystacklen)
{
s->needle=needle;
s->needlelen=needlelen;
switch(needlelen)
{
case 0: s->method=no_search; break;
case 1: s->method=use_memchr; break;
case 2:
case 3:
case 4:
case 5:
case 6: s->method=memchr_and_memcmp; break;
default:
if(max_haystacklen <= needlelen + 64)
{
s->method=memchr_and_memcmp;
}else{
INT32 tmp, h;
unsigned INT32 hsize, e, max;
|
d63edd | 1996-08-06 | Fredrik Hübinette (Hubbe) | | unsigned char *q;
|
b0ddc5 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | struct link *ptr;
hsize=52+(max_haystacklen >> 7) - (needlelen >> 8);
max =13+(max_haystacklen >> 4) - (needlelen >> 5);
if(hsize > NELEM(s->set))
{
hsize=NELEM(s->set);
}else{
for(e=8;e<hsize;e+=e);
hsize=e;
}
for(e=0;e<hsize;e++) s->set[e]=0;
hsize--;
if(max > needlelen) max=needlelen;
max=(max-sizeof(INT32)+1) & -sizeof(INT32);
if(max > MEMSEARCH_LINKS) max=MEMSEARCH_LINKS;
ptr=& s->links[0];
|
d63edd | 1996-08-06 | Fredrik Hübinette (Hubbe) | | q=(unsigned char *)needle;
|
b0ddc5 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
#if BYTEORDER == 4321
for(tmp=e=0;e<sizeof(INT32)-1;e++)
{
tmp<<=8;
tmp|=*(q++);
}
#endif
for(e=0;e<max;e++)
{
#if BYTEORDER == 4321
tmp<<=8;
tmp|=*(q++);
#else
|
d63edd | 1996-08-06 | Fredrik Hübinette (Hubbe) | | tmp=EXTRACT_INT(q);
|
b0ddc5 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | q++;
#endif
h=tmp;
h+=h>>7;
h+=h>>17;
h&=hsize;
ptr->offset=e;
ptr->key=tmp;
ptr->next=s->set[h];
s->set[h]=ptr;
ptr++;
}
s->hsize=hsize;
s->max=max;
s->method=hubbe_search;
}
}
}
char *memory_search(struct mem_searcher *s,
char *haystack,
SIZE_T haystacklen)
{
if(s->needlelen > haystacklen) return 0;
switch(s->method)
{
case no_search:
return haystack;
case use_memchr:
return MEMCHR(haystack,s->needle[0],haystacklen);
case memchr_and_memcmp:
{
char *end,c,*needle;
SIZE_T needlelen;
needle=s->needle;
needlelen=s->needlelen;
end=haystack + haystacklen - needlelen+1;
c=needle[0];
needle++;
needlelen--;
while((haystack=MEMCHR(haystack,c,end-haystack)))
if(!MEMCMP(++haystack,needle,needlelen))
return haystack-1;
return 0;
}
case hubbe_search:
{
INT32 tmp, h;
char *q, *end;
register struct link *ptr;
|
7022d8 | 1997-04-06 | Fredrik Hübinette (Hubbe) | | end=haystack+haystacklen;
|
b0ddc5 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | q=haystack + s->max - sizeof(INT32);
q=(char *)( ((long)q) & -sizeof(INT32));
|
7022d8 | 1997-04-06 | Fredrik Hübinette (Hubbe) | | for(;q<=end-sizeof(INT32);q+=s->max)
|
b0ddc5 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | {
h=tmp=*(INT32 *)q;
h+=h>>7;
h+=h>>17;
h&=s->hsize;
for(ptr=s->set[h];ptr;ptr=ptr->next)
{
char *where;
if(ptr->key != tmp) continue;
where=q-ptr->offset;
if(where<haystack) continue;
if(where+s->needlelen>end) return 0;
if(!MEMCMP(where,s->needle,s->needlelen))
return where;
}
}
}
}
return 0;
}
char *my_memmem(char *needle,
SIZE_T needlelen,
char *haystack,
SIZE_T haystacklen)
{
struct mem_searcher tmp;
init_memsearch(&tmp, needle, needlelen, haystacklen);
return memory_search(&tmp, haystack, haystacklen);
}
|
9dd500 | 1996-12-06 | Fredrik Hübinette (Hubbe) | |
void memfill(char *to,
INT32 tolen,
char *from,
INT32 fromlen,
INT32 offset)
{
if(fromlen==1)
{
MEMSET(to, *from, tolen);
}
else if(tolen>0)
{
INT32 tmp=MINIMUM(tolen, fromlen - offset);
MEMCPY(to, from + offset, tmp);
to+=tmp;
tolen-=tmp;
if(tolen > 0)
{
tmp=MINIMUM(tolen, fromlen);
MEMCPY(to, from, tmp);
from=to;
to+=tmp;
tolen-=tmp;
while(tolen>0)
{
tmp=MINIMUM(tolen, fromlen);
MEMCPY(to, from, MINIMUM(tolen, fromlen));
fromlen+=tmp;
tolen-=tmp;
to+=tmp;
}
}
}
}
|