📄 utility.cpp
字号:
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 + -