20 September 2010

arrayCopy

Hi folks,

While looking at the usage of the method System.arraycopy
in Java, I found it very useful function.
for example, in java.util.ArrayList it is doing may useful shifting operations.

So, I decide to try to write a similar function, but instead of using the pattern "func (src, dest)" of java, I used instead the pattern "func(dest, src)" of C.

The Header file:
#ifndef ARRAYUTIL_H
#define ARRAYUTIL_H

#include <stddef.h>

/**
* dest destination array
* dIndex index to which we will start copying
* src source array
* sIndex index from which we will start copying
* len number of elements that will be copied from source array
* destArrLen the length of the destination array (hence C doesn't know any length info about passed arrays)
* size the size of the type of the array (ex: if the array of type long, put in this parameter sizeof(long))
*/
void arraryCopy(void *dest, int dIndex, const void* src, int sIndex, int len, int destArrLen, size_t size);

#endif // ARRAYUTIL_H


The impl file:
#include <string.h>
#include <stdint.h>
#include <stdlib.h>

#include <arrays/ArrayUtil.h>

void arraryCopy(void *dest, int dIndex, const void* src, int sIndex, int len, int destLen, size_t size)
{
uint8_t *udest = (uint8_t*) dest;
uint8_t *usrc = (uint8_t*) src;
dIndex *= size;
sIndex *= size;
len *= size;
destLen *= size;

if (src != dest)
{
memcpy(&udest[dIndex], &usrc[sIndex], len);
}else
{
if (dIndex > sIndex)
{
uint8_t *tmp = (uint8_t*) calloc(destLen, size);
memcpy(tmp, &udest[dIndex], (destLen-dIndex));
memcpy(&udest[dIndex], &usrc[sIndex], len);
memcpy(&udest[dIndex+len], tmp, (destLen-dIndex));
free(tmp);
}else if (sIndex > dIndex)
{
memcpy(&udest[dIndex], &usrc[sIndex], (destLen-sIndex)+1);
}else
return;
}
}


And, testing it:
#include <stdio.h>
#include <arrays/ArrayUtil.h>

int main(void)
{
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

arraryCopy(arr, 1, arr, 2, 1, 10, sizeof(int));

int i;
for (i=0; i<9; i++) // the len became 9 here because we do shift left by 1
printf("%i ", arr[i]);

return 0;
}


No comments: