📄 pchannel.cxx
字号:
else {
receivePosition = sendPosition;
do {
if (abortCommandString) // aborted
return PFalse;
if ((nextChar = ReadCharWithTimeout(timeout)) < 0)
return PFalse;
} while (!ReceiveCommandString(nextChar,
command, receivePosition, sendPosition));
// nextChar = GetNextChar(command, receivePosition);
sendPosition = receivePosition;
}
}
}
return PFalse;
}
PBoolean PChannel::Shutdown(ShutdownValue)
{
return PFalse;
}
PChannel * PChannel::GetBaseReadChannel() const
{
return (PChannel *)this;
}
PChannel * PChannel::GetBaseWriteChannel() const
{
return (PChannel *)this;
}
PString PChannel::GetErrorText(ErrorGroup group) const
{
return GetErrorText(lastErrorCode[group], lastErrorNumber[group]);
}
PBoolean PChannel::ConvertOSError(int status, ErrorGroup group)
{
Errors lastError;
int osError;
PBoolean ok = ConvertOSError(status, lastError, osError);
SetErrorValues(lastError, osError, group);
return ok;
}
PBoolean PChannel::SetErrorValues(Errors errorCode, int errorNum, ErrorGroup group)
{
lastErrorCode[NumErrorGroups] = lastErrorCode[group] = errorCode;
lastErrorNumber[NumErrorGroups] = lastErrorNumber[group] = errorNum;
return errorCode == NoError;
}
#ifndef P_HAS_RECVMSG
PBoolean PChannel::Read(const VectorOfSlice & slices)
{
PINDEX length = 0;
VectorOfSlice::const_iterator r;
for (r = slices.begin(); r != slices.end(); ++r) {
PBoolean stat = Read(r->iov_base, r->iov_len);
length += lastReadCount;
lastReadCount = length;
if (!stat)
return PFalse;
}
return PTrue;
}
PBoolean PChannel::Write(const VectorOfSlice & slices)
{
PINDEX length = 0;
VectorOfSlice::const_iterator r;
for (r = slices.begin(); r != slices.end(); ++r) {
PBoolean stat = Write(r->iov_base, r->iov_len);
length += lastWriteCount;
lastWriteCount = length;
if (!stat)
return PFalse;
}
return PTrue;
}
#endif // P_HAS_RECVMSG
///////////////////////////////////////////////////////////////////////////////
// PIndirectChannel
PIndirectChannel::PIndirectChannel()
{
readChannel = writeChannel = NULL;
writeAutoDelete = readAutoDelete = PFalse;
}
PObject::Comparison PIndirectChannel::Compare(const PObject & obj) const
{
PAssert(PIsDescendant(&obj, PIndirectChannel), PInvalidCast);
const PIndirectChannel & other = (const PIndirectChannel &)obj;
return readChannel == other.readChannel &&
writeChannel == other.writeChannel ? EqualTo : GreaterThan;
}
PString PIndirectChannel::GetName() const
{
PReadWaitAndSignal mutex(channelPointerMutex);
if (readChannel != NULL && readChannel == writeChannel)
return readChannel->GetName();
PStringStream name;
name << "R<";
if (readChannel != NULL)
name << readChannel->GetName();
name << "> T<";
if (writeChannel != NULL)
name << writeChannel->GetName();
name << '>';
return name;
}
PBoolean PIndirectChannel::Close()
{
PBoolean retval = PTrue;
flush();
channelPointerMutex.StartRead();
if (readChannel != NULL)
retval = readChannel->Close();
if (readChannel != writeChannel && writeChannel != NULL)
retval = writeChannel->Close() && retval;
channelPointerMutex.EndRead();
channelPointerMutex.StartWrite();
PChannel * r = readChannel;
PChannel * w = writeChannel;
readChannel = NULL;
writeChannel = NULL;
if (readAutoDelete)
delete r;
if (r != w && writeAutoDelete)
delete w;
channelPointerMutex.EndWrite();
return retval;
}
PBoolean PIndirectChannel::IsOpen() const
{
PReadWaitAndSignal mutex(channelPointerMutex);
if (readChannel != NULL && readChannel == writeChannel)
return readChannel->IsOpen();
PBoolean returnValue = readChannel != NULL ? readChannel->IsOpen() : PFalse;
if (writeChannel != NULL)
returnValue = writeChannel->IsOpen() || returnValue;
return returnValue;
}
PBoolean PIndirectChannel::Read(void * buf, PINDEX len)
{
flush();
PReadWaitAndSignal mutex(channelPointerMutex);
if (readChannel == NULL) {
SetErrorValues(NotOpen, EBADF, LastReadError);
return PFalse;
}
readChannel->SetReadTimeout(readTimeout);
PBoolean returnValue = readChannel->Read(buf, len);
SetErrorValues(readChannel->GetErrorCode(LastReadError),
readChannel->GetErrorNumber(LastReadError),
LastReadError);
lastReadCount = readChannel->GetLastReadCount();
return returnValue;
}
PBoolean PIndirectChannel::Write(const void * buf, PINDEX len)
{
flush();
PReadWaitAndSignal mutex(channelPointerMutex);
if (writeChannel == NULL) {
SetErrorValues(NotOpen, EBADF, LastWriteError);
return PFalse;
}
writeChannel->SetWriteTimeout(writeTimeout);
PBoolean returnValue = writeChannel->Write(buf, len);
SetErrorValues(writeChannel->GetErrorCode(LastWriteError),
writeChannel->GetErrorNumber(LastWriteError),
LastWriteError);
lastWriteCount = writeChannel->GetLastWriteCount();
return returnValue;
}
PBoolean PIndirectChannel::Shutdown(ShutdownValue value)
{
PReadWaitAndSignal mutex(channelPointerMutex);
if (readChannel != NULL && readChannel == writeChannel)
return readChannel->Shutdown(value);
PBoolean returnValue = readChannel != NULL ? readChannel->Shutdown(value) : PFalse;
if (writeChannel != NULL)
returnValue = writeChannel->Shutdown(value) || returnValue;
return returnValue;
}
PString PIndirectChannel::GetErrorText(ErrorGroup group) const
{
if (readChannel != NULL)
return readChannel->GetErrorText(group);
if (writeChannel != NULL)
return writeChannel->GetErrorText(group);
return PChannel::GetErrorText(group);
}
PBoolean PIndirectChannel::Open(PChannel & channel)
{
return Open(&channel, (PBoolean)PFalse);
}
PBoolean PIndirectChannel::Open(PChannel * channel, PBoolean autoDelete)
{
return Open(channel, channel, autoDelete, autoDelete);
}
PBoolean PIndirectChannel::Open(PChannel * readChan,
PChannel * writeChan,
PBoolean autoDeleteRead,
PBoolean autoDeleteWrite)
{
flush();
channelPointerMutex.StartWrite();
if (readChannel != NULL)
readChannel->Close();
if (readChannel != writeChannel && writeChannel != NULL)
writeChannel->Close();
if (readAutoDelete)
delete readChannel;
if (readChannel != writeChannel && writeAutoDelete)
delete writeChannel;
readChannel = readChan;
readAutoDelete = autoDeleteRead;
writeChannel = writeChan;
writeAutoDelete = autoDeleteWrite;
channelPointerMutex.EndWrite();
return IsOpen() && OnOpen();
}
PBoolean PIndirectChannel::OnOpen()
{
return PTrue;
}
PBoolean PIndirectChannel::SetReadChannel(PChannel * channel, PBoolean autoDelete)
{
if (readChannel != NULL)
return SetErrorValues(DeviceInUse, EEXIST);
channelPointerMutex.StartWrite();
readChannel = channel;
readAutoDelete = autoDelete;
channelPointerMutex.EndWrite();
return IsOpen();
}
PBoolean PIndirectChannel::SetWriteChannel(PChannel * channel, PBoolean autoDelete)
{
if (writeChannel != NULL)
return SetErrorValues(DeviceInUse, EEXIST);
channelPointerMutex.StartWrite();
writeChannel = channel;
writeAutoDelete = autoDelete;
channelPointerMutex.EndWrite();
return IsOpen();
}
PChannel * PIndirectChannel::GetBaseReadChannel() const
{
PReadWaitAndSignal mutex(channelPointerMutex);
return readChannel != NULL ? readChannel->GetBaseReadChannel() : 0;
}
PChannel * PIndirectChannel::GetBaseWriteChannel() const
{
PReadWaitAndSignal mutex(channelPointerMutex);
return writeChannel != NULL ? writeChannel->GetBaseWriteChannel() : 0;
}
///////////////////////////////////////////////////////////////////////////////
// PFile
PFile::~PFile()
{
Close();
}
PObject::Comparison PFile::Compare(const PObject & obj) const
{
PAssert(PIsDescendant(&obj, PFile), PInvalidCast);
return path.Compare(((const PFile &)obj).path);
}
PBoolean PFile::Rename(const PString & newname, PBoolean force)
{
Close();
if (!ConvertOSError(Rename(path, newname, force) ? 0 : -1))
return PFalse;
path = path.GetDirectory() + newname;
return PTrue;
}
PBoolean PFile::Close()
{
if (!IsOpen())
return SetErrorValues(NotOpen, EBADF);
flush();
#ifdef WOT_NO_FILESYSTEM
PBoolean ok = PTrue;
#else
PBoolean ok = ConvertOSError(_close(os_handle));
#endif
os_handle = -1;
if (removeOnClose)
Remove();
return ok;
}
PBoolean PFile::Read(void * buffer, PINDEX amount)
{
flush();
#ifdef WOT_NO_FILESYSTEM
lastReadCount = 0;
#else
lastReadCount = _read(GetHandle(), buffer, amount);
#endif
return ConvertOSError(lastReadCount, LastReadError) && lastReadCount > 0;
}
PBoolean PFile::Write(const void * buffer, PINDEX amount)
{
flush();
#ifdef WOT_NO_FILESYSTEM
lastWriteCount = amount;
#else
lastWriteCount = _write(GetHandle(), buffer, amount);
#endif
return ConvertOSError(lastWriteCount, LastWriteError) && lastWriteCount >= amount;
}
PBoolean PFile::Open(const PFilePath & name, OpenMode mode, int opts)
{
Close();
SetFilePath(name);
return Open(mode, opts);
}
off_t PFile::GetLength() const
{
#ifdef WOT_NO_FILESYSTEM
return 0;
#else
off_t pos = _lseek(GetHandle(), 0, SEEK_CUR);
off_t len = _lseek(GetHandle(), 0, SEEK_END);
PAssertOS(_lseek(GetHandle(), pos, SEEK_SET) != (off_t)-1);
return len;
#endif
}
PBoolean PFile::IsEndOfFile() const
{
((PFile *)this)->flush();
return GetPosition() >= GetLength();
}
PBoolean PFile::SetPosition(off_t pos, FilePositionOrigin origin)
{
#ifdef WOT_NO_FILESYSTEM
return PTrue;
#else
return _lseek(GetHandle(), pos, origin) != (off_t)-1;
#endif
}
PBoolean PFile::Copy(const PFilePath & oldname, const PFilePath & newname, PBoolean force)
{
PFile oldfile(oldname, ReadOnly);
if (!oldfile.IsOpen())
return PFalse;
PFile newfile(newname,
WriteOnly, Create|Truncate|(force ? MustExist : Exclusive));
if (!newfile.IsOpen())
return PFalse;
PCharArray buffer(10000);
off_t amount = oldfile.GetLength();
while (amount > 10000) {
if (!oldfile.Read(buffer.GetPointer(), 10000))
return PFalse;
if (!newfile.Write((const char *)buffer, 10000))
return PFalse;
amount -= 10000;
}
if (!oldfile.Read(buffer.GetPointer(), (int)amount))
return PFalse;
if (!newfile.Write((const char *)buffer, (int)amount))
return PFalse;
return newfile.Close();
}
// End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -