-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmemswap.h
47 lines (41 loc) · 1.08 KB
/
memswap.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/* memory helper
*
* This Works is placed under the terms of the Copyright Less License,
* see file COPYRIGHT.CLL. USE AT OWN RISK, ABSOLUTELY NO WARRANTY.
*/
/* abcdef -> fedcba
*/
static void
memrev(void *base, size_t len)
{
char *a, *b, c;
if (len)
for (a = base, b = a+len-1; a<b; a++, b--)
c = *a, *a = *b, *b = c;
}
/* Swap memory area within itself.
* The both parts do not need to be of equal size.
*
* !off!
* before: abcdEF.
* after: EFabcd.
* !-len-!
*/
static void *
memswap(void *base, size_t off, size_t len)
{
if (!base || !off || off>=len)
return base;
/* Optimization to just touch each element once:
*
* XXX TODO XXX Handle special case where GCD(off,len)==off
* XXX TODO XXX Handle special case where GCD(off,len)==1
* XXX TODO XXX Handle common case with GCD(off,len) iterations
*
* For now, touch each element twice:
*/
memrev(base, off); /* abcdEFG -> dcbaEFG */
memrev(((char *)base)+off, len-off); /* dcbaEFG -> dcbaGFE */
memrev(base, len); /* dcbaGFE -> EFGabcd */
return base;
}