📄 pchannel.cxx
字号:
temp = command[pos++] - '0';
if (command[pos] < '0' || command[pos] > '7')
return temp;
temp += command[pos++] - '0';
if (command[pos] < '0' || command[pos] > '7')
return temp;
temp += command[pos++] - '0';
return temp;
}
BOOL PChannel::ReceiveCommandString(int nextChar,
const PString & reply, PINDEX & pos, PINDEX start)
{
if (nextChar != GetNextChar(reply, pos)) {
pos = start;
return FALSE;
}
PINDEX dummyPos = pos;
return GetNextChar(reply, dummyPos) < 0;
}
BOOL PChannel::SendCommandString(const PString & command)
{
abortCommandString = FALSE;
int nextChar;
PINDEX sendPosition = 0;
PTimeInterval timeout;
SetWriteTimeout(10000);
while (!abortCommandString) { // not aborted
nextChar = GetNextChar(command, sendPosition, &timeout);
switch (nextChar) {
default :
if (!WriteChar(nextChar))
return FALSE;
break;
case NextCharEndOfString :
return TRUE; // Success!!
case NextCharSend :
break;
case NextCharDelay : // Delay in send
PThread::Current()->Sleep(timeout);
break;
case NextCharWait : // Wait for reply
PINDEX receivePosition = sendPosition;
if (GetNextChar(command, receivePosition) < 0) {
SetReadTimeout(timeout);
while (ReadChar() >= 0)
if (abortCommandString) // aborted
return FALSE;
}
else {
receivePosition = sendPosition;
do {
if (abortCommandString) // aborted
return FALSE;
if ((nextChar = ReadCharWithTimeout(timeout)) < 0)
return FALSE;
} while (!ReceiveCommandString(nextChar,
command, receivePosition, sendPosition));
// nextChar = GetNextChar(command, receivePosition);
sendPosition = receivePosition;
}
}
}
return FALSE;
}
BOOL PChannel::Shutdown(ShutdownValue)
{
return FALSE;
}
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]);
}
BOOL PChannel::ConvertOSError(int status, ErrorGroup group)
{
Errors lastError;
int osError;
BOOL ok = ConvertOSError(status, lastError, osError);
SetErrorValues(lastError, osError, group);
return ok;
}
BOOL 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
BOOL PChannel::Read(const VectorOfSlice & slices)
{
PINDEX length = 0;
VectorOfSlice::const_iterator r;
for (r = slices.begin(); r != slices.end(); ++r) {
BOOL stat = Read(r->iov_base, r->iov_len);
length += lastReadCount;
lastReadCount = length;
if (!stat)
return FALSE;
}
return TRUE;
}
BOOL PChannel::Write(const VectorOfSlice & slices)
{
PINDEX length = 0;
VectorOfSlice::const_iterator r;
for (r = slices.begin(); r != slices.end(); ++r) {
BOOL stat = Write(r->iov_base, r->iov_len);
length += lastWriteCount;
lastWriteCount = length;
if (!stat)
return FALSE;
}
return TRUE;
}
#endif // P_HAS_RECVMSG
///////////////////////////////////////////////////////////////////////////////
// PIndirectChannel
PIndirectChannel::PIndirectChannel()
{
readChannel = writeChannel = NULL;
writeAutoDelete = readAutoDelete = FALSE;
}
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;
}
BOOL PIndirectChannel::Close()
{
BOOL retval = TRUE;
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;
}
BOOL PIndirectChannel::IsOpen() const
{
PReadWaitAndSignal mutex(channelPointerMutex);
if (readChannel != NULL && readChannel == writeChannel)
return readChannel->IsOpen();
BOOL returnValue = readChannel != NULL ? readChannel->IsOpen() : FALSE;
if (writeChannel != NULL)
returnValue = writeChannel->IsOpen() || returnValue;
return returnValue;
}
BOOL PIndirectChannel::Read(void * buf, PINDEX len)
{
flush();
PReadWaitAndSignal mutex(channelPointerMutex);
if (readChannel == NULL) {
SetErrorValues(NotOpen, EBADF, LastReadError);
return FALSE;
}
readChannel->SetReadTimeout(readTimeout);
BOOL returnValue = readChannel->Read(buf, len);
SetErrorValues(readChannel->GetErrorCode(LastReadError),
readChannel->GetErrorNumber(LastReadError),
LastReadError);
lastReadCount = readChannel->GetLastReadCount();
return returnValue;
}
BOOL PIndirectChannel::Write(const void * buf, PINDEX len)
{
flush();
PReadWaitAndSignal mutex(channelPointerMutex);
if (writeChannel == NULL) {
SetErrorValues(NotOpen, EBADF, LastWriteError);
return FALSE;
}
writeChannel->SetWriteTimeout(writeTimeout);
BOOL returnValue = writeChannel->Write(buf, len);
SetErrorValues(writeChannel->GetErrorCode(LastWriteError),
writeChannel->GetErrorNumber(LastWriteError),
LastWriteError);
lastWriteCount = writeChannel->GetLastWriteCount();
return returnValue;
}
BOOL PIndirectChannel::Shutdown(ShutdownValue value)
{
PReadWaitAndSignal mutex(channelPointerMutex);
if (readChannel != NULL && readChannel == writeChannel)
return readChannel->Shutdown(value);
BOOL returnValue = readChannel != NULL ? readChannel->Shutdown(value) : FALSE;
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);
}
BOOL PIndirectChannel::Open(PChannel & channel)
{
return Open(&channel, (BOOL)FALSE);
}
BOOL PIndirectChannel::Open(PChannel * channel, BOOL autoDelete)
{
return Open(channel, channel, autoDelete, autoDelete);
}
BOOL PIndirectChannel::Open(PChannel * readChan,
PChannel * writeChan,
BOOL autoDeleteRead,
BOOL 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();
}
BOOL PIndirectChannel::OnOpen()
{
return TRUE;
}
BOOL PIndirectChannel::SetReadChannel(PChannel * channel, BOOL autoDelete)
{
if (readChannel != NULL)
return SetErrorValues(DeviceInUse, EEXIST);
channelPointerMutex.StartWrite();
readChannel = channel;
readAutoDelete = autoDelete;
channelPointerMutex.EndWrite();
return IsOpen();
}
BOOL PIndirectChannel::SetWriteChannel(PChannel * channel, BOOL 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);
}
BOOL PFile::Rename(const PString & newname, BOOL force)
{
Close();
if (!ConvertOSError(Rename(path, newname, force) ? 0 : -1))
return FALSE;
path = path.GetDirectory() + newname;
return TRUE;
}
BOOL PFile::Close()
{
if (!IsOpen())
return SetErrorValues(NotOpen, EBADF);
flush();
#ifdef WOT_NO_FILESYSTEM
BOOL ok = TRUE;
#else
BOOL ok = ConvertOSError(_close(os_handle));
#endif
os_handle = -1;
if (removeOnClose)
Remove();
return ok;
}
BOOL 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;
}
BOOL 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;
}
BOOL 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
}
BOOL PFile::IsEndOfFile() const
{
((PFile *)this)->flush();
return GetPosition() >= GetLength();
}
BOOL PFile::SetPosition(off_t pos, FilePositionOrigin origin)
{
#ifdef WOT_NO_FILESYSTEM
return TRUE;
#else
return _lseek(GetHandle(), pos, origin) != (off_t)-1;
#endif
}
BOOL PFile::Copy(const PFilePath & oldname, const PFilePath & newname, BOOL force)
{
PFile oldfile(oldname, ReadOnly);
if (!oldfile.IsOpen())
return FALSE;
PFile newfile(newname,
WriteOnly, Create|Truncate|(force ? MustExist : Exclusive));
if (!newfile.IsOpen())
return FALSE;
PCharArray buffer(10000);
off_t amount = oldfile.GetLength();
while (amount > 10000) {
if (!oldfile.Read(buffer.GetPointer(), 10000))
return FALSE;
if (!newfile.Write((const char *)buffer, 10000))
return FALSE;
amount -= 10000;
}
if (!oldfile.Read(buffer.GetPointer(), (int)amount))
return FALSE;
if (!newfile.Write((const char *)buffer, (int)amount))
return FALSE;
return newfile.Close();
}
// End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -