⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utility.cpp

📁 fastcopy是一个非常快速的数据拷贝软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
static char *utility_id = 
	"@(#)Copyright (C) H.Shirouzu 2004-2008   utility.cpp	Ver1.70";
/* ========================================================================
	Project  Name			: general routine
	Create					: 2004-09-15(Wed)
	Update					: 2008-02-02(Sat)
	Copyright				: H.Shirouzu
	Reference				: 
	======================================================================== */

#include <stdio.h>
#include <stddef.h>
#include "utility.h"
#include "resource.h"

/*=========================================================================
  僋儔僗 丗 Condition
  奣  梫 丗 忦審曄悢僋儔僗
  愢  柧 丗 
  拲  堄 丗 
=========================================================================*/
Condition::Condition(void)
{
	hEvents = NULL;
}

Condition::~Condition(void)
{
	UnInitialize();
}

BOOL Condition::Initialize(int _max_threads)
{
	UnInitialize();

	max_threads = _max_threads;
	waitEvents = new WaitEvent [max_threads];
	hEvents = new HANDLE [max_threads];
	for (int wait_id=0; wait_id < max_threads; wait_id++) {
		if (!(hEvents[wait_id] = ::CreateEvent(0, FALSE, FALSE, NULL)))
			return	FALSE;
		waitEvents[wait_id] = CLEAR_EVENT;
	}
	::InitializeCriticalSection(&cs);
	waitCnt = 0;
	return	TRUE;
}

void Condition::UnInitialize(void)
{
	if (hEvents) {
		while (--max_threads >= 0)
			::CloseHandle(hEvents[max_threads]);
		delete [] hEvents;
		delete [] waitEvents;
		hEvents = NULL;
		waitEvents = NULL;
		::DeleteCriticalSection(&cs);
	}
}

BOOL Condition::Wait(DWORD timeout)
{
	int		wait_id = 0;

	for (wait_id=0; wait_id < max_threads && waitEvents[wait_id] != CLEAR_EVENT; wait_id++)
		;
	if (wait_id == max_threads) {	// 捠忢偼偁傝偊側偄
		MessageBox(0, "Detect too many wait threads", "FastCopy", MB_OK);
		return	FALSE;
	}
	waitEvents[wait_id] = WAIT_EVENT;
	waitCnt++;
	UnLock();

	DWORD	status = ::WaitForSingleObject(hEvents[wait_id], timeout);

	Lock();
	--waitCnt;
	waitEvents[wait_id] = CLEAR_EVENT;

	return	status == WAIT_TIMEOUT ? FALSE : TRUE;
}

void Condition::Notify(void)	// 尰忬偱偼丄柊偭偰偄傞僗儗僢僪慡堳傪婲偙偡
{
	if (waitCnt > 0) {
		for (int wait_id=0, done_cnt=0; wait_id < max_threads; wait_id++) {
			if (waitEvents[wait_id] == WAIT_EVENT) {
				::SetEvent(hEvents[wait_id]);
				waitEvents[wait_id] = DONE_EVENT;
				if (++done_cnt >= waitCnt)
					break;
			}
		}
	}
}

/*=========================================================================
  僋儔僗 丗 VBuf
  奣  梫 丗 壖憐儊儌儕娗棟僋儔僗
  愢  柧 丗 
  拲  堄 丗 
=========================================================================*/
VBuf::VBuf(int _size, int _max_size)
{
	Init();

	if (_size || _max_size)
		AllocBuf(_size, _max_size);
}

VBuf::~VBuf()
{
	if (buf)
		FreeBuf();
}

void VBuf::Init(void)
{
	buf = NULL;
	size = usedSize = maxSize = 0;
}

BOOL VBuf::AllocBuf(int _size, int _max_size)
{
	if (_max_size == 0)
		_max_size = _size;
	maxSize = _max_size;

// 1page 暘偩偗梋寁偵妋曐乮buffer over flow 専弌梡乯
	if (!(buf = (BYTE *)::VirtualAlloc(NULL, maxSize + PAGE_SIZE, MEM_RESERVE, PAGE_READWRITE))) {
		Init();
		return	FALSE;
	}
	return	Grow(_size);
}

BOOL VBuf::LockBuf(void)
{
	return	::VirtualLock(buf, size);
}

void VBuf::FreeBuf(void)
{
	if (buf)
		::VirtualFree(buf, 0, MEM_RELEASE);
	Init();
}

BOOL VBuf::Grow(int grow_size)
{
	if (size + grow_size > maxSize)
		return	FALSE;

	if (grow_size && !::VirtualAlloc(buf + size, grow_size, MEM_COMMIT, PAGE_READWRITE))
		return	FALSE;

	size += grow_size;
	return	TRUE;
}

/*=========================================================================
	奼挘 strtok()
		"" 偵弌偔傢偡偲丄"" 偺拞恎傪庢傝弌偡
		token 偺慜屻偵嬻敀偑偁傟偽庢傝彍偔
		偦傟埲奜偼丄strtok_r() 偲摨偠
=========================================================================*/
void *strtok_pathV(void *str, const void *sep, void **p)
{
	const void	*quote=QUOTE_V, *org_sep = sep;

	if (str)
		*p = str;
	else
		str = *p;

	if (!*p)
		return	NULL;

	// 摢偩偟
	while (GetChar(str, 0) && (strchrV(sep, GetChar(str, 0)) || GetChar(str, 0) == ' '))
		str = MakeAddr(str, 1);
	if (GetChar(str, 0) == 0)
		return	NULL;

	// 廔抂専弌
	void	*in = str, *out = str;
	for ( ; GetChar(in, 0); in = MakeAddr(in, 1)) {
		if (sep == org_sep) {	// 捠忢 mode
			if (GetChar(in, 0) == '"') {
				sep = quote;	// quote mode 偵慗堏
			}
			else if (strchrV(sep, GetChar(in, 0))) {
				break;
			}
			else {
				SetChar(out, 0, GetChar(in, 0));
				out = MakeAddr(out, 1);
			}
		}
		else {					// quote mode
			if (GetChar(in, 0) == '"') {
				sep = org_sep;	// 捠忢 mode 偵慗堏
			}
			else {
				SetChar(out, 0, GetChar(in, 0));
				out = MakeAddr(out, 1);
			}
		}
	}
	*p = GetChar(in, 0) ? MakeAddr(in, 1) : NULL;
	SetChar(out, 0, 0);

	// 枛旜偺嬻敀傪庢傝彍偔
	for (out = MakeAddr(out, -1); out >= str && GetChar(out, 0) == ' '; out = MakeAddr(out, -1))
		SetChar(out, 0, 0);

	return	str;
}

/*=========================================================================
	僐儅儞僪儔僀儞夝愅乮CommandLineToArgvW API 偺 ANSI斉乯
		CommandLineToArgvW() 偲摨偠偔丄曉傝抣偺奐曻偼屇傃尦偱偡傞偙偲
=========================================================================*/
void **CommandLineToArgvV(void *cmdLine, int *_argc)
{
#define MAX_ARG_ALLOC	16
	int&	argc = *_argc;
	void	**argv = NULL, *p;
	void	*separantor = IS_WINNT_V ? (char *)L" \t" : " \t";

	argc = 0;
	while (1) {
		if ((argc % MAX_ARG_ALLOC) == 0)
			argv = (void **)realloc(argv, (argc + MAX_ARG_ALLOC) * sizeof(void *));
		if ((argv[argc] = strtok_pathV(argc ? NULL : cmdLine, separantor, &p)) == NULL)
			break;
		argc++;
	}

	return	argv;
}

/*=========================================================================
	PathArray
=========================================================================*/
PathArray::PathArray(void)
{
	num = 0;
	pathArray = NULL;
}

PathArray::PathArray(const PathArray &src)
{
	num = 0;
	pathArray = NULL;
	*this = src;
}

PathArray::~PathArray()
{
	Init();
}

void PathArray::Init(void)
{
	while (--num >= 0)
		free(pathArray[num]);
	free(pathArray);
	num = 0;
	pathArray = NULL;
}

int PathArray::RegisterMultiPath(const void *_multi_path, const void *separator)
{
	void	*multi_path = strdupV(_multi_path);
	void	*tok, *p;
	int		cnt = 0;

	for (tok = strtok_pathV(multi_path, separator, &p); tok; tok = strtok_pathV(NULL, separator, &p)) {
		if (RegisterPath(tok))
			cnt++;
	}
	free(multi_path);
	return	cnt;
}

int PathArray::GetMultiPath(void *multi_path, int max_len, const void *separator, const void *escape_char)
{
	void	*buf = multi_path;
	void	*FMT_STRSTR_V = IS_WINNT_V ? (void *)L"%s%s" : (void *)"%s%s";
	int		len = 0;
	int		escape_val = GetChar(escape_char, 0);

	SetChar(multi_path, 0, 0);
	for (int i=0; i < num; i++) {
		if (max_len - len - strlenV(pathArray[i]) < 3)
			break;
		if (i)
			len += sprintfV(MakeAddr(buf, len), FMT_STR_V, separator);
		len += sprintfV(MakeAddr(buf, len), escape_val && strchrV(pathArray[i], escape_val) ? FMT_QUOTE_STR_V : FMT_STR_V, pathArray[i]);
	}
	return	len;
}

BOOL PathArray::SetPath(int idx, const void *path)
{
	int	size = (strlenV(path) + 1) * CHAR_LEN_V;
	pathArray[idx] = malloc(size);
	memcpy(pathArray[idx], path, size);
	return	TRUE;
}

BOOL PathArray::RegisterPath(const void *path)
{
	for (int i=0; i < num; i++)
		if (lstrcmpiV(path, pathArray[i]) == 0)
			return	FALSE;

#define MAX_ALLOC	100
	if ((num % MAX_ALLOC) == 0)
		pathArray = (void **)realloc(pathArray, (num + MAX_ALLOC) * sizeof(void *));
	SetPath(num++, path);

	return	TRUE;
}

BOOL PathArray::ReplacePath(int idx, void *new_path)
{
	if (idx >= num)
		return	FALSE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -