/* copy_bytes.c
* -- three functions for safe byte copying
* Thomas Padron-McCarthy (padrone@lysator.liu.se), 1991
* This file latest updated: Sept 21, 1991
*
* We don't know how memcpy handles overlapping data,
* so we use the two functions "copy_bytes_up" and "copy_bytes_down"
* to copy data between overlapping areas.
* "copy_bytes_down" should be used when copying from an area
* to an overlapping area with a LOWER address.
* "copy_bytes_up" should be used when copying from an area
* to an overlapping area with a HIGHER address.
* The function "copy_bytes" can decides for itself which of
* those two functions to use.
*
* I have tried to write efficient code. Don't laugh.
* I use pointers in register variables,
* and use the pointers themselves to count,
* i. e. I don't use an extra integer counter.
* When possible I use integer copying instead of char copying,
* hoping that this will be faster.
*/
#include "copy_bytes.h"
void copy_bytes_up(to_cp, from_cp, nr_bytes)
register char *to_cp, *from_cp;
register int nr_bytes;
{
if ( (int)to_cp % sizeof(int) == 0
&& (int)from_cp % sizeof(int) == 0
&& nr_bytes % sizeof(int) == 0) {
register int *to_ip, *from_ip, *end_ip;
to_ip = (int *)to_cp;
from_ip = (int *)from_cp;
end_ip = from_ip + nr_bytes / sizeof(int);
while (from_ip != end_ip)
*to_ip++ = *from_ip++;
}
else {
register char *end_cp;
end_cp = from_cp + nr_bytes;
while (from_cp != end_cp)
*to_cp++ = *from_cp++;
}
} /* copy_bytes_up */
void copy_bytes_down(to_cp, from_cp, nr_bytes)
register char *to_cp, *from_cp;
register int nr_bytes;
{
if ( (int)to_cp % sizeof(int) == 0
&& (int)from_cp % sizeof(int) == 0
&& nr_bytes % sizeof(int) == 0) {
register int *to_ip, *from_ip, *end_ip;
nr_bytes /= sizeof(int);
to_ip = (int *)to_cp;
from_ip = (int *)from_cp;
end_ip = from_ip - 1;
from_ip = from_ip + nr_bytes - 1;
to_ip = to_ip + nr_bytes - 1;
while (from_ip != end_ip)
*to_ip-- = *from_ip--;
}
else {
register char *end_cp;
end_cp = from_cp - 1;
from_cp = from_cp + nr_bytes - 1;
to_cp = to_cp + nr_bytes - 1;
while (from_cp != end_cp)
*to_cp-- = *from_cp--;
}
} /* copy_bytes_down */
void copy_bytes(to_cp, from_cp, nr_bytes)
register char *to_cp, *from_cp;
register int nr_bytes;
{
if (to_cp < from_cp)
copy_bytes_up(to_cp, from_cp, nr_bytes);
else
copy_bytes_down(to_cp, from_cp, nr_bytes);
} /* copy_bytes */
syntax highlighted by Code2HTML, v. 0.9.1