标准仿C语言 memset、memcpy、memmove函数(含C#版)

ε祈祈猫儿з 提交于 2019-12-07 09:16:36

标准仿C语言  memset、memcpy、memmove函数

      前段时间,移植了C的网络加解密算法到C#,其中遇到很多问题,核心问题大多都是字节拷贝问题,今天有时间整理了一下相关的API,废话不多说直接贴源码:(值得注意的是memmove函数,支持数据重叠,详情参照http://blog.csdn.net/yujun_wu/article/details/4999565)

一> C++版

/* 
* @brief: 将dst中当前位置后面的 count 个字节用 val 替换并返回 dst 
* @param s	- 数据内存的起始地址
* @param c	- 替换后的值
* @param n	- 要替换的长度
* @return 返回原数据首地址
*/
void* memset(void* s, int c, size_t n)
{
	assert(s);
	
	unsigned char* p = (unsigned char*)s;

	while (n > 0)
	{
		*p++ = (unsigned char)c;
		--n;
	}

	return s;
}

/*
* @brief: 用于从src拷贝count个字节到dest,如果目标区域和源区域有重叠的话
	,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。
	但复制后src内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同
* @param dst	- 目标内存地址
* @param src	- 原内存地址
* @param count	- 要拷贝的长度
* @return 返回dst地址
*/
void* memmove(void* dst, const void* src, size_t count)
{
	assert(dst);
	assert(src);

	void * ret = dst;
	if (dst <= src || (char *)dst >= ((char *)src + count))
	{
		while (count--)
		{
			*(char *)dst = *(char *)src;
			dst = (char *)dst + 1;
			src = (char *)src + 1;
		}
	}
	else
	{
		dst = (char *)dst + count - 1;
		src = (char *)src + count - 1;
		
		while (count--)
		{
			*(char *)dst = *(char *)src;
			dst = (char *)dst - 1;
			src = (char *)src - 1;
		}
	}

	return(ret);
}

/*
* @brief: 用于从src拷贝count个字节到dest(不能包含重叠)
* @param dst	- 目标内存地址
* @param src	- 原内存地址
* @param count	- 要拷贝的长度
* @return 返回dst地址
*/
void* memcpy(void* dst, const void* src, size_t count)
{
	assert(dst);
	assert(src);

	void* ret = dst;

	/*
	* copy from lower addresses to higher addresses
	*/
	while (count--)
	{
		*(char *)dst = *(char *)src;
		dst = (char *)dst + 1;
		src = (char *)src + 1;
	}

	return(ret);
}


二> C#版
// 标准仿C memcpy函数
unsafe public void* memcpy(void* dst, void* src, uint count)
{
	System.Diagnostics.Debug.Assert(dst != null);
	System.Diagnostics.Debug.Assert(src != null);

	void* ret = dst;

	/*
	* copy from lower addresses to higher addresses
	*/
	while (count-- > 0)
	{
		*(char*)dst = *(char*)src;
		dst = (char*)dst + 1;
		src = (char*)src + 1;
	}

	return (ret);
}

// 标准仿C memmove函数
unsafe public void* memmove(void* dst, void* src, uint count)
{
	System.Diagnostics.Debug.Assert(dst != null);
	System.Diagnostics.Debug.Assert(src != null);

	void* ret = dst;

	if (dst <= src || (char *)dst >= ((char *)src + count))
	{
		while (count-- > 0)
		{
			*(char*)dst = *(char*)src;
			dst = (char*)dst + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		dst = (char *)dst + count - 1;
		src = (char *)src + count - 1;
		while (count-- > 0)
		{
			*(char*)dst = *(char*)src;
			dst = (char*)dst - 1;
			src = (char*)src - 1;
		}
	}

	return(ret);
}

// 标准仿C memset函数
unsafe public void* memset(void* s, int c, uint n)
{
	byte* p = (byte*)s;

	while (n > 0)
	{
		*p++ = (byte)c;
		--n;
	}

	return s;
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!