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

📄 osutils.cxx

📁 windows mobile phone source code
💻 CXX
📖 第 1 页 / 共 4 页
字号:

#include <ctype.h>

class PSimpleThread : public PThread
{
    PCLASSINFO(PSimpleThread, PThread);
  public:
    PSimpleThread(
      const PNotifier & notifier,
      INT parameter,
      AutoDeleteFlag deletion,
      Priority priorityLevel,
      const PString & threadName,
      PINDEX stackSize
    );
    void Main();
  protected:
    PNotifier callback;
    INT parameter;
};

static PMutex * PTraceMutex = NULL;

#ifndef __NUCLEUS_PLUS__
static ostream * PErrorStream = &cerr;
#else
static ostream * PErrorStream = NULL;
#endif

ostream & PGetErrorStream()
{
  return *PErrorStream;
}


void PSetErrorStream(ostream * s)
{
#ifndef __NUCLEUS_PLUS__
  PErrorStream = s != NULL ? s : &cerr;
#else
  PErrorStream = s;
#endif
}

//////////////////////////////////////////////////////////////////////////////

#if !defined(__NUCLEUS_PLUS__) && !defined(_WIN32_WCE)
static ostream * PTraceStream = &cerr;
#else

#ifdef __NUCLEUS_PLUS__ 
static ostream * PTraceStream = 0L;
#endif
#ifdef _WIN32_WCE
static YWinCEOStream * PTraceStream = &cerr;
#endif

#endif

static unsigned PTraceOptions = PTrace::FileAndLine;
static unsigned PTraceLevelThreshold = 0;
static unsigned PTraceBlockIndentLevel = 0;
static PTimeInterval ApplicationStartTick = PTimer::Tick();

void PTrace::SetStream(ostream * s)
{
#if !defined(__NUCLEUS_PLUS__) && !defined(_WIN32_WCE)
  PTraceStream = s != NULL ? s : &cerr;
#else

#ifdef __NUCLEUS_PLUS__ 
  PTraceStream = s;
#endif
#ifdef _WIN32_WCE
  PTraceStream = &cerr;
#endif

#endif
}


void PTrace::Initialise(unsigned level, const char * filename, unsigned options)
{
#if PTRACING
  PProcess & process = PProcess::Current();
#endif

  // If we have a tracing version, then open trace file and set modes
  PTraceOptions = options;
  PTraceLevelThreshold = level;

  if (filename != NULL) {
#if PMEMORY_CHECK
    BOOL ignoreAllocations = PMemoryHeap::SetIgnoreAllocations(TRUE);
#endif
    PTextFile * traceOutput = new PTextFile(filename, PFile::WriteOnly);
#if PMEMORY_CHECK
    PMemoryHeap::SetIgnoreAllocations(ignoreAllocations);
#endif
    if (traceOutput->IsOpen())
      PTrace::SetStream(traceOutput);
    else {
      PTRACE(0, process.GetName() << "Could not open trace output file \"" << filename << '"');
      delete traceOutput;
    }
  }

  PTRACE(1, process.GetName()
         << "\tVersion " << process.GetVersion(TRUE)
         << " by " << process.GetManufacturer()
         << " on " << process.GetOSClass() << ' ' << process.GetOSName()
         << " (" << process.GetOSVersion() << '-' << process.GetOSHardware()
         << ") at " << PTime().AsString("yyyy/M/d h:mm:ss.uuu"));
}


void PTrace::SetOptions(unsigned options)
{
  PTraceOptions |= options;
}


void PTrace::ClearOptions(unsigned options)
{
  PTraceOptions &= ~options;
}


unsigned PTrace::GetOptions()
{
  return PTraceOptions;
}


void PTrace::SetLevel(unsigned level)
{
  PTraceLevelThreshold = level;
}


unsigned PTrace::GetLevel()
{
  return PTraceLevelThreshold;
}


BOOL PTrace::CanTrace(unsigned level)
{
  return level <= PTraceLevelThreshold;
}


ostream & PTrace::Begin(unsigned level, const char * fileName, int lineNum)
{
  if (PTraceMutex == NULL) {
    // This flag must never be destroyed before it is finished with. As we
    // cannot assure destruction at the right time we simply allocate it and
    // NEVER destroy it! This is OK as the only reason for its destruction is
    // the program is exiting and then who cares?
#if PMEMORY_CHECK
    BOOL ignoreAllocations = PMemoryHeap::SetIgnoreAllocations(TRUE);
#endif
    PTraceMutex = new PMutex;
#if PMEMORY_CHECK
    PMemoryHeap::SetIgnoreAllocations(ignoreAllocations);
#endif
  }

  PTraceMutex->Wait();

  if (level == UINT_MAX)
    return *PTraceStream;

  if ((PTraceOptions&SystemLogStream) != 0) {
    unsigned lvl = level+PSystemLog::Warning;
    if (lvl >= PSystemLog::NumLogLevels)
      lvl = PSystemLog::NumLogLevels-1;
    ((PSystemLog*)PTraceStream)->SetLevel((PSystemLog::Level)lvl);
  }
  else {
    if ((PTraceOptions&DateAndTime) != 0) {
      PTime now;
      *PTraceStream << now.AsString("yyyy/MM/dd hh:mm:ss\t");
    }

    if ((PTraceOptions&Timestamp) != 0)
      *PTraceStream << setprecision(3) << setw(10) << (PTimer::Tick()-ApplicationStartTick) << '\t';

    if ((PTraceOptions&Thread) != 0) {
      PThread * thread = PThread::Current();
      if (thread == NULL)
        *PTraceStream << setw(23) << "<<unknown>>";
      else {
        PString name = thread->GetThreadName();
        if (name.GetLength() <= 23)
          *PTraceStream << setw(23) << name;
        else
          *PTraceStream << name.Left(10) << "..." << name.Right(10);
      }
      *PTraceStream << '\t';
    }

    if ((PTraceOptions&ThreadAddress) != 0)
      *PTraceStream << hex << setfill('0')
                    << setw(7) << (unsigned)PThread::Current()
                    << dec << setfill(' ') << '\t';
  }

  if ((PTraceOptions&TraceLevel) != 0)
    *PTraceStream << level << '\t';

  if ((PTraceOptions&FileAndLine) != 0 && fileName != NULL) {
    const char * file = strrchr(fileName, '/');
    if (file != NULL)
      file++;
    else {
      file = strrchr(fileName, '\\');
      if (file != NULL)
        file++;
      else
        file = fileName;
    }

    *PTraceStream << setw(16) << file << '(' << lineNum << ")\t";
  }

  return *PTraceStream;
}


ostream & PTrace::End(ostream & s)
{
  /* Only output if there is something to output, this prevents some blank trace
     entries from appearing under some patholgical conditions. Unfortunately if
     stderr is used the unitbuf flag causes the out_waiting() not to work so we 
     must suffer with blank lines in that case.
   */
  if ((s.flags()&ios::unitbuf) != 0 || s.rdbuf()->out_waiting() > 0) {
    if ((PTraceOptions&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;

  PTraceBlockIndentLevel += 2;

  if ((PTraceOptions&Blocks) != 0) {
    ostream & s = PTrace::Begin(1, file, line);
    for (unsigned i = 0; i < PTraceBlockIndentLevel; i++)
      s << '=';
    s << "> " << name << PTrace::End;
  }
}


PTrace::Block::~Block()
{
  if ((PTraceOptions&Blocks) != 0) {
    ostream & s = PTrace::Begin(1, file, line);
    s << '<';
    for (unsigned i = 0; i < PTraceBlockIndentLevel; i++)
      s << '=';
    s << ' ' << name << PTrace::End;
  }

  PTraceBlockIndentLevel -= 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)
{
  Construct();
}


PTimer::PTimer(const PTimeInterval & time)
  : resetTime(time)
{
  Construct();
}


void PTimer::Construct()
{
  state = Stopped;

  timerList = PProcess::Current().GetTimerList();

  timerList->listMutex.Wait();
  timerList->Append(this);
  timerList->listMutex.Signal();

  timerList->processingMutex.Wait();
  StartRunning(TRUE);
}


PTimer & PTimer::operator=(DWORD milliseconds)
{
  timerList->processingMutex.Wait();
  resetTime.SetInterval(milliseconds);
  StartRunning(oneshot);
  return *this;
}


PTimer & PTimer::operator=(const PTimeInterval & time)
{
  timerList->processingMutex.Wait();
  resetTime = time;
  StartRunning(oneshot);
  return *this;
}


PTimer::~PTimer()
{
  timerList->listMutex.Wait();
  timerList->Remove(this);
  timerList->listMutex.Signal();
  timerList->inTimeoutMutex.Wait();
  timerList->inTimeoutMutex.Signal();
}


void PTimer::RunContinuous(const PTimeInterval & time)
{
  timerList->processingMutex.Wait();
  resetTime = time;
  StartRunning(FALSE);
}


void PTimer::StartRunning(BOOL once)
{
  PTimeInterval::operator=(resetTime);
  oneshot = once;
  state = (*this) != 0 ? Starting : Stopped;

#if defined(P_PLATFORM_HAS_THREADS)
  if (IsRunning())
    PProcess::Current().SignalTimerChange();
#endif

  // This must have been set by the caller
  timerList->processingMutex.Signal();
}


void PTimer::Stop()
{
  timerList->processingMutex.Wait();
  state = Stopped;
  SetInterval(0);
  timerList->processingMutex.Signal();
}


void PTimer::Pause()
{
  timerList->processingMutex.Wait();
  if (IsRunning())
    state = Paused;
  timerList->processingMutex.Signal();
}


void PTimer::Resume()
{
  timerList->processingMutex.Wait();
  if (state == Paused)
    state = Starting;
  timerList->processingMutex.Signal();
}


void PTimer::Reset()
{
  timerList->processingMutex.Wait();
  StartRunning(oneshot);
}


void PTimer::OnTimeout()
{
  if (!callback.IsNULL())
    callback(*this, IsRunning());
}


void PTimer::Process(const PTimeInterval & delta, PTimeInterval & minTimeLeft)
{
  /*Ideally there should be a processingMutex for each individual timer, but
    that seems incredibly profligate of system resources as there  can be a
    LOT of PTimer instances about. So use one one mutex for all.
   */
  timerList->processingMutex.Wait();

  switch (state) {
    case Starting :
      state = Running;
      if (resetTime < minTimeLeft)
        minTimeLeft = resetTime;
      break;

    case Running :
      operator-=(delta);

      if (milliseconds > 0) {
        if (milliseconds < minTimeLeft.GetMilliSeconds())
          minTimeLeft = *this;
      }
      else {
        if (oneshot) {
          SetInterval(0);
          state = Stopped;
        }
        else {
          PTimeInterval::operator=(resetTime);
          if (resetTime < minTimeLeft)
            minTimeLeft = resetTime;
        }

        timerList->processingMutex.Signal();

        /* This must be outside the mutex or if OnTimeout() changes the
           timer value (quite plausible) it deadlocks.
         */
        OnTimeout();
        return;
      }
      break;

    default : // Stopped or Paused, do nothing.
      break;
  }

  timerList->processingMutex.Signal();
}


///////////////////////////////////////////////////////////////////////////////
// PTimerList

PTimerList::PTimerList()
{
  DisallowDeleteObjects();
}


PTimeInterval PTimerList::Process()
{
  PINDEX i;
  PTimeInterval minTimeLeft = PMaxTimeInterval;

  listMutex.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++) {
    PTimer & timer = (*this)[i];
    inTimeoutMutex.Wait();
    listMutex.Signal();
    timer.Process(sampleTime, minTimeLeft);
    listMutex.Wait();
    inTimeoutMutex.Signal();
  }
  
  listMutex.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;

⌨️ 快捷键说明

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