📄 ptlib.cxx
字号:
/*
* ptlib.cxx
*
* General implementation of classes for Microsoft operating systems.
*
* Portable Windows Library
*
* Copyright (c) 1993-1998 Equivalence Pty. Ltd.
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Portable Windows Library.
*
* The Initial Developer of the Original Code is Equivalence Pty. Ltd.
*
* Portions are Copyright (C) 1993 Free Software Foundation, Inc.
* All Rights Reserved.
*
* Contributor(s): ______________________________________.
*
* $Revision: 19340 $
* $Author: rjongbloed $
* $Date: 2008-01-24 04:13:55 +0000 (Thu, 24 Jan 2008) $
*/
#include <ptlib.h>
#include <ptlib/pprocess.h>
#if !P_USE_INLINES
#include <ptlib/osutil.inl>
#include <ptlib/msos/ptlib/ptlib.inl>
#endif
#ifndef _WIN32_WCE
#include <share.h>
#endif
ostream & operator<<(ostream & s, PInt64 v)
{
char buffer[25];
if ((s.flags()&ios::hex) != 0)
return s << _ui64toa(v, buffer, 16);
if ((s.flags()&ios::oct) != 0)
return s << _ui64toa(v, buffer, 8);
if (v < 0) {
s << '-';
v = -v;
}
return s << _i64toa(v, buffer, 10);
}
ostream & operator<<(ostream & s, PUInt64 v)
{
char buffer[25];
return s << _ui64toa(v, buffer, (s.flags()&ios::oct) ? 8 : ((s.flags()&ios::hex) ? 16 : 10));
}
const int MaxDigits = (64+2)/3+1; // Maximum is 22 digit octal number, plus sign
static void GetDigits(PBoolean sign, istream & s, char * buffer)
{
PINDEX count = 0;
while (isspace(s.peek()))
s.get();
if (s.peek() == '+')
s.get(); // Skip leading '+'
else if (sign && s.peek() == '-')
s.get(buffer[count++]);
if ((s.flags()&ios::oct) != 0) {
while (isdigit(s.peek()) && s.peek() < '8' && count < MaxDigits)
s.get(buffer[count++]);
}
else if ((s.flags()&ios::hex) != 0) {
while (isxdigit(s.peek()) && count < MaxDigits)
s.get(buffer[count++]);
}
else {
while (isdigit(s.peek()) && count < MaxDigits)
s.get(buffer[count++]);
}
buffer[count] = '\0';
if (count > (buffer[0] == '-' ? 1 : 0))
return;
s.clear(ios::failbit);
}
istream & operator>>(istream & s, PInt64 & v)
{
char b[MaxDigits+1];
GetDigits(PTrue, s, b);
v = _atoi64(b);
return s;
}
istream & operator>>(istream & s, PUInt64 & v)
{
char b[MaxDigits+1];
GetDigits(PFalse, s, b);
v = _atoi64(b);
return s;
}
PInt64 PString::AsInt64(unsigned base) const
{
if (base == 10)
return _atoi64(theArray);
PAssert(base >= 2 && base <= 36, PInvalidParameter);
PInt64 total = 0;
const char * ptr = theArray;
while (isspace(*ptr))
ptr++;
PBoolean negative = *ptr == '-';
if (*ptr == '-' || *ptr == '+')
ptr++;
for (;;) {
unsigned c = *ptr++;
if (c < '0')
break;
if (c <= '9')
c -= '0';
else
c = toupper(c) - 'A' + 10;
if (c >= base)
break;
total = base * total + c;
}
if (negative)
return -total;
else
return total;
}
PUInt64 PString::AsUnsigned64(unsigned base) const
{
PAssert(base >= 2 && base <= 36, PInvalidParameter);
PUInt64 total = 0;
const char * ptr = theArray;
while (isspace(*ptr))
ptr++;
for (;;) {
unsigned c = *ptr++;
if (c < '0')
break;
if (c <= '9')
c -= '0';
else
c = toupper(c) - 'A' + 10;
if (c >= base)
break;
total = base * total + c;
}
return total;
}
///////////////////////////////////////////////////////////////////////////////
// PTime
struct tm * PTime::os_localtime(const time_t * clock, struct tm * tb)
{
struct tm * tp = ::localtime(clock);
if (tp != NULL)
return tp;
memset(tb, 0, sizeof(*tb));
return tb;
}
struct tm * PTime::os_gmtime(const time_t * clock, struct tm * tb)
{
struct tm * tp = ::gmtime(clock);
if (tp != NULL)
return tp;
memset(tb, 0, sizeof(*tb));
return tb;
}
///////////////////////////////////////////////////////////////////////////////
// PChannel
void PChannel::Construct()
{
}
PString PChannel::GetName() const
{
PAssertAlways(PUnimplementedFunction);
return PString();
}
PBoolean PChannel::Read(void *, PINDEX)
{
PAssertAlways(PUnimplementedFunction);
return PFalse;
}
PBoolean PChannel::Write(const void *, PINDEX)
{
PAssertAlways(PUnimplementedFunction);
return PFalse;
}
PBoolean PChannel::Close()
{
return PFalse;
}
///////////////////////////////////////////////////////////////////////////////
// Directories
PDirectory PDirectory::GetParent() const
{
if (IsRoot())
return *this;
return *this + "..";
}
PBoolean PDirectory::Change(const PString & p)
{
PDirectory d = p;
if (d[0] != '\\')
if (_chdrive(toupper(d[0])-'A'+1) != 0)
return PFalse;
return _chdir(d + ".") == 0;
}
PBoolean PDirectory::Filtered()
{
#ifdef UNICODE
PString name(fileinfo.cFileName);
#else
char * name = fileinfo.cFileName;
#endif // UNICODE
if (strcmp(name, ".") == 0)
return PTrue;
if (strcmp(name, "..") == 0)
return PTrue;
if (scanMask == PFileInfo::AllPermissions)
return PFalse;
PFileInfo inf;
PAssert(PFile::GetInfo(*this+name, inf), POperatingSystemError);
return (inf.type&scanMask) == 0;
}
PBoolean PDirectory::IsRoot() const
{
if ((*this)[1] == ':')
return GetLength() == 3;
PINDEX pos = FindOneOf("/\\", 2);
return pos == GetLength();
}
PDirectory PDirectory::GetRoot() const
{
if ((*this)[1] == ':')
return Left(3);
return Left(FindOneOf("/\\", 2));
}
PStringArray PDirectory::GetPath() const
{
PStringArray path;
if (IsEmpty())
return path;
if ((*this)[1] == ':')
path = Tokenise("/\\", PFalse);
else {
path = Mid(2).Tokenise("/\\", PFalse);
path[0].Splice("\\\\", 0);
}
PINDEX last = path.GetSize()-1;
while (path[last].IsEmpty())
path.SetSize(last--);
return path;
}
PBoolean PDirectory::GetInfo(PFileInfo & info) const
{
return PFile::GetInfo(*this + GetEntryName(), info);
}
///////////////////////////////////////////////////////////////////////////////
// File Path
PFilePath::PFilePath(const PString & str)
: PCaselessString(PDirectory::CreateFullPath(str, PFalse))
{
}
PFilePath::PFilePath(const char * cstr)
: PCaselessString(PDirectory::CreateFullPath(cstr, PFalse))
{
}
PFilePath::PFilePath(const char * prefix, const char * dir)
{
if (dir != NULL) {
PDirectory tmpdir(dir);
operator=(tmpdir);
}
else {
PString path = getenv("TMPDIR");
if (path.IsEmpty()) {
path = getenv("TMP");
if (path.IsEmpty())
path = getenv("TEMP");
}
if (path.IsEmpty() || path[path.GetLength()-1] != '\\')
path += '\\';
*this = path;
}
if (prefix != NULL)
*this += prefix;
else
*this += "PW";
*this += "XXXXXX";
PAssert(_mktemp(GetPointer()) != NULL, "Could not make temporary file");
}
void PFilePath::AssignContents(const PContainer & cont)
{
PCaselessString::AssignContents(cont);
PCaselessString::AssignContents(PDirectory::CreateFullPath(*this, PFalse));
}
static PINDEX GetVolumeSubStringLength(const PString & path)
{
if (path[1] == ':')
return 2;
if (path[0] == '\\' && path[1] == '\\') {
PINDEX backslash = path.Find('\\', 2);
if (backslash != P_MAX_INDEX) {
backslash = path.Find('\\', backslash+1);
if (backslash != P_MAX_INDEX)
return backslash;
}
}
PINDEX backslash = path.Find('\\');
if (backslash != P_MAX_INDEX)
return backslash;
return 0;
}
PCaselessString PFilePath::GetVolume() const
{
return Left(GetVolumeSubStringLength(*this));
}
PDirectory PFilePath::GetDirectory() const
{
PINDEX backslash = FindLast('\\');
if (backslash != P_MAX_INDEX)
return Left(backslash+1);
return PCaselessString();
}
PCaselessString PFilePath::GetPath() const
{
return operator()(GetVolumeSubStringLength(*this), FindLast('\\', GetLength()-2));
}
PCaselessString PFilePath::GetFileName() const
{
PINDEX backslash = FindLast('\\', GetLength()-2);
if (backslash == P_MAX_INDEX)
backslash = 0;
else
backslash++;
return Mid(backslash);
}
PCaselessString PFilePath::GetTitle() const
{
PINDEX backslash = FindLast('\\', GetLength()-2);
if (backslash == P_MAX_INDEX)
backslash = 0;
else
backslash++;
PINDEX last_dot = FindLast('.');
if (last_dot < backslash)
last_dot = P_MAX_INDEX;
return operator()(backslash, last_dot-1);
}
PCaselessString PFilePath::GetType() const
{
PINDEX slash = FindLast('\\');
if (slash == P_MAX_INDEX)
slash = 0;
PINDEX dot = FindLast('.');
if (dot < slash)
return PCaselessString();
return operator()(dot, P_MAX_INDEX);
}
void PFilePath::SetType(const PCaselessString & type)
{
PINDEX dot = Find('.', FindLast('\\'));
if (dot != P_MAX_INDEX)
Splice(type, dot, GetLength()-dot);
else
*this += type;
}
///////////////////////////////////////////////////////////////////////////////
// PFile
void PFile::SetFilePath(const PString & newName)
{
if (!IsOpen())
path = newName;
}
PBoolean PFile::Access(const PFilePath & name, OpenMode mode)
{
int accmode;
switch (mode) {
case ReadOnly :
#ifndef R_OK
#define R_OK 4
#endif
accmode = R_OK;
break;
case WriteOnly :
#ifndef W_OK
#define W_OK 2
#endif
accmode = W_OK;
break;
default :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -