📄 osutils.cxx
字号:
PErrorStream = s != NULL ? s : &cerr;
}
///////////////////////////////////////////////////////////////////////////////
ostream * PTrace::Stream = &cerr;
unsigned PTrace::Options = PTrace::FileAndLine;
unsigned PTrace::LevelThreshold = 0;
unsigned PTrace::Block::IndentLevel = 0;
static PTimeInterval ApplicationStartTick = PTimer::Tick();
void PTrace::SetStream(ostream * s)
{
Stream = s != NULL ? s : &cerr;
}
void PTrace::SetOptions(unsigned options)
{
Options |= options;
}
void PTrace::ClearOptions(unsigned options)
{
Options &= ~options;
}
unsigned PTrace::GetOptions()
{
return Options;
}
void PTrace::SetLevel(unsigned level)
{
LevelThreshold = level;
}
unsigned PTrace::GetLevel()
{
return LevelThreshold;
}
BOOL PTrace::CanTrace(unsigned level)
{
return level <= LevelThreshold;
}
static PMutex PTraceMutex;
ostream & PTrace::Begin(unsigned level, const char * fileName, int lineNum)
{
PTraceMutex.Wait();
if ((Options&SystemLogStream) != 0) {
unsigned lvl = level+PSystemLog::Warning;
if (lvl >= PSystemLog::NumLogLevels)
lvl = PSystemLog::NumLogLevels-1;
((PSystemLog*)Stream)->SetLevel((PSystemLog::Level)lvl);
}
else {
if ((Options&DateAndTime) != 0) {
PTime now;
*Stream << now.AsString("yyyy/MM/dd hh:mm:ss\t");
}
if ((Options&Timestamp) != 0)
*Stream << setprecision(3) << setw(10) << (PTimer::Tick()-ApplicationStartTick) << '\t';
if ((Options&Thread) != 0)
*Stream << PThread::Current() << '\t';
}
if ((Options&TraceLevel) != 0)
*Stream << level << '\t';
if ((Options&FileAndLine) != 0 && fileName != NULL) {
const char * file = strrchr(fileName, '/');
if (file != NULL)
file++;
else {
file = strrchr(fileName, '\\');
if (file != NULL)
file++;
else
file = fileName;
}
*Stream << file << '(' << lineNum << ")\t";
}
return *Stream;
}
ostream & PTrace::End(ostream & s)
{
if ((Options&SystemLogStream) != 0)
s.flush();
else
s << endl;
PTraceMutex.Signal();
return s;
}
PTrace::Block::Block(const char * fileName, int lineNum, const char * traceName)
{
file = fileName;
line = lineNum;
name = traceName;
IndentLevel += 2;
if ((Options&Blocks) != 0) {
ostream & s = PTrace::Begin(1, file, line);
for (unsigned i = 0; i < IndentLevel; i++)
s << '=';
s << "> " << name << PTrace::End;
}
}
PTrace::Block::~Block()
{
if ((Options&Blocks) != 0) {
ostream & s = PTrace::Begin(1, file, line);
s << '<';
for (unsigned i = 0; i < IndentLevel; i++)
s << '=';
s << ' ' << name << PTrace::End;
}
IndentLevel -= 2;
}
///////////////////////////////////////////////////////////////////////////////
// PDirectory
void PDirectory::CloneContents(const PDirectory * d)
{
CopyContents(*d);
}
///////////////////////////////////////////////////////////////////////////////
// PTimer
PTimer::PTimer(long millisecs, int seconds, int minutes, int hours, int days)
: resetTime(millisecs, seconds, minutes, hours, days)
{
state = Stopped;
timeoutThread = NULL;
StartRunning(TRUE);
}
PTimer::PTimer(const PTimeInterval & time)
: resetTime(time)
{
state = Stopped;
timeoutThread = NULL;
StartRunning(TRUE);
}
PTimer & PTimer::operator=(DWORD milliseconds)
{
resetTime = (PInt64)milliseconds;
StartRunning(oneshot);
return *this;
}
PTimer & PTimer::operator=(const PTimeInterval & time)
{
resetTime = time;
StartRunning(oneshot);
return *this;
}
PTimer::~PTimer()
{
PAssert(timeoutThread == NULL || PThread::Current() != timeoutThread, "Timer destroyed in OnTimeout()");
if (state == Running)
PProcess::Current().GetTimerList()->RemoveTimer(this);
}
void PTimer::RunContinuous(const PTimeInterval & time)
{
resetTime = time;
StartRunning(FALSE);
}
void PTimer::StartRunning(BOOL once)
{
if (state == Running && timeoutThread == NULL)
PProcess::Current().GetTimerList()->RemoveTimer(this);
PTimeInterval::operator=(resetTime);
oneshot = once;
state = (*this) != 0 ? Running : Stopped;
if (state == Running && timeoutThread == NULL)
PProcess::Current().GetTimerList()->AppendTimer(this);
}
void PTimer::Stop()
{
if (state == Running && timeoutThread == NULL)
PProcess::Current().GetTimerList()->RemoveTimer(this);
state = Stopped;
SetInterval(0);
}
void PTimer::Pause()
{
if (state == Running) {
if (timeoutThread == NULL)
PProcess::Current().GetTimerList()->RemoveTimer(this);
state = Paused;
}
}
void PTimer::Resume()
{
if (state == Paused) {
if (timeoutThread == NULL)
PProcess::Current().GetTimerList()->AppendTimer(this);
state = Running;
}
}
void PTimer::OnTimeout()
{
if (!callback.IsNULL())
callback(*this, state == Running);
}
BOOL PTimer::Process(const PTimeInterval & delta, PTimeInterval & minTimeLeft)
{
operator-=(delta);
if (milliseconds > 0) {
if (milliseconds < minTimeLeft.GetMilliSeconds())
minTimeLeft = milliseconds;
return FALSE;
}
timeoutThread = PThread::Current();
if (oneshot) {
operator=(PTimeInterval(0));
state = Stopped;
}
else {
operator=(resetTime);
if (resetTime < minTimeLeft)
minTimeLeft = resetTime;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// PTimerList
PTimerList::PTimerList()
{
DisallowDeleteObjects();
}
void PTimerList::AppendTimer(PTimer * timer)
{
mutex.Wait();
PInternalTimerList::InsertAt(0, timer);
mutex.Signal();
#if defined(P_PLATFORM_HAS_THREADS)
PProcess::Current().SignalTimerChange();
#endif
}
void PTimerList::RemoveTimer(PTimer * timer)
{
mutex.Wait();
PInternalTimerList::Remove(timer);
mutex.Signal();
#if defined(P_PLATFORM_HAS_THREADS)
PProcess::Current().SignalTimerChange();
#endif
}
PTimeInterval PTimerList::Process()
{
PINDEX i;
PTimeInterval minTimeLeft = PMaxTimeInterval;
PInternalTimerList timeouts;
timeouts.DisallowDeleteObjects();
mutex.Wait();
PTimeInterval now = PTimer::Tick();
PTimeInterval sampleTime;
if (lastSample == 0)
sampleTime = 0;
else {
sampleTime = now - lastSample;
if (now < lastSample)
sampleTime += PMaxTimeInterval;
}
lastSample = now;
for (i = 0; i < GetSize(); i++)
if ((*this)[i].Process(sampleTime, minTimeLeft))
timeouts.Append(RemoveAt(i--));
mutex.Signal();
for (i = 0; i < timeouts.GetSize(); i++)
timeouts[i].OnTimeout();
mutex.Wait();
for (i = 0; i < timeouts.GetSize(); i++) {
timeouts[i].timeoutThread = NULL;
if (timeouts[i].IsRunning())
Append(timeouts.GetAt(i));
}
mutex.Signal();
return minTimeLeft;
}
///////////////////////////////////////////////////////////////////////////////
// PArgList
PArgList::PArgList(const char * theArgStr,
const char * theArgumentSpec,
BOOL optionsBeforeParams)
{
// get the program arguments
if (theArgStr != NULL)
SetArgs(theArgStr);
// if we got an argument spec - so process them
if (theArgumentSpec != NULL)
Parse(theArgumentSpec, optionsBeforeParams);
}
PArgList::PArgList(const PString & theArgStr,
const char * argumentSpecPtr,
BOOL optionsBeforeParams)
{
// get the program arguments
SetArgs(theArgStr);
// if we got an argument spec - so process them
if (argumentSpecPtr != NULL)
Parse(argumentSpecPtr, optionsBeforeParams);
}
PArgList::PArgList(const PString & theArgStr,
const PString & argumentSpecStr,
BOOL optionsBeforeParams)
{
// get the program arguments
SetArgs(theArgStr);
// if we got an argument spec - so process them
Parse(argumentSpecStr, optionsBeforeParams);
}
PArgList::PArgList(int theArgc, char ** theArgv,
const char * theArgumentSpec,
BOOL optionsBeforeParams)
{
// get the program arguments
SetArgs(theArgc, theArgv);
// if we got an argument spec - so process them
if (theArgumentSpec != NULL)
Parse(theArgumentSpec, optionsBeforeParams);
}
PArgList::PArgList(int theArgc, char ** theArgv,
const PString & theArgumentSpec,
BOOL optionsBeforeParams)
{
// get the program name and path
SetArgs(theArgc, theArgv);
// we got an argument spec - so process them
Parse(theArgumentSpec, optionsBeforeParams);
}
void PArgList::SetArgs(const PString & argStr)
{
argumentArray.SetSize(0);
const char * str = argStr;
for (;;) {
while (isspace(*str)) // Skip leading whitespace
str++;
if (*str == '\0')
break;
PString & arg = argumentArray[argumentArray.GetSize()];
while (*str != '\0' && !isspace(*str)) {
switch (*str) {
case '"' :
str++;
while (*str != '\0' && *str != '"')
arg += *str++;
if (*str != '\0')
str++;
break;
case '\'' :
str++;
while (*str != '\0' && *str != '\'')
arg += *str++;
if (*str != '\0')
str++;
break;
default :
if (str[0] == '\\' && str[1] != '\0')
str++;
arg += *str++;
}
}
}
SetArgs(argumentArray);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -