📄 pchannel.cxx
字号:
/* * pchannel.cxx * * Operating System utilities. * * 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): ______________________________________. * * $Log: pchannel.cxx,v $ * Revision 1.7 2000/06/26 11:17:20 robertj * Nucleus++ port (incomplete). * * Revision 1.6 1999/07/06 08:55:05 robertj * Fixed bug in PFile::Copy, does not write last chunk of data to new file. * * Revision 1.5 1999/06/17 14:44:42 robertj * Fixed incorrect comparison of open write channel * * Revision 1.4 1999/06/17 13:38:11 robertj * Fixed race condition on indirect channel close, mutex needed in PIndirectChannel. * * Revision 1.3 1999/02/22 10:10:12 robertj * Changed channel output flush to remove double Write() call. * * Revision 1.2 1999/01/31 00:57:18 robertj * Fixed bug when opening an already open file, should close it! * * Revision 1.1 1998/11/30 12:46:19 robertj * Initial revision * */#include <ptlib.h>#include <ctype.h>///////////////////////////////////////////////////////////////////////////////// PChannelPChannelStreamBuffer::PChannelStreamBuffer(PChannel * chan) : channel(PAssertNULL(chan)){}int PChannelStreamBuffer::overflow(int c){ if (pbase() == NULL) { if (eback() == 0) setp(buffer, &buffer[sizeof(buffer)]); else { char * halfway = &buffer[sizeof(buffer)/2]; setp(buffer, halfway); setg(halfway, &buffer[sizeof(buffer)], &buffer[sizeof(buffer)]); } } int bufSize = pptr() - pbase(); if (bufSize > 0) { setp(pbase(), epptr()); if (!channel->Write(pbase(), bufSize)) return EOF; } if (c != EOF) { *pptr() = (char)c; pbump(1); } return 0;}int PChannelStreamBuffer::underflow(){ if (eback() == NULL) { if (pbase() == 0) setg(buffer, &buffer[sizeof(buffer)], &buffer[sizeof(buffer)]); else { char * halfway = &buffer[sizeof(buffer)/2]; setp(buffer, halfway); setg(halfway, &buffer[sizeof(buffer)], &buffer[sizeof(buffer)]); } } if (gptr() != egptr()) return (BYTE)*gptr(); if (!channel->Read(eback(), egptr() - eback()) || channel->GetErrorCode() != PChannel::NoError) return EOF; PINDEX count = channel->GetLastReadCount(); char * p = egptr() - count; memmove(p, eback(), count); setg(eback(), p, egptr()); return (BYTE)*p;}int PChannelStreamBuffer::sync(){ int inAvail = egptr() - gptr(); if (inAvail > 0) { setg(eback(), egptr(), egptr()); if (channel->IsDescendant(PFile::Class())) ((PFile *)channel)->SetPosition(-inAvail, PFile::Current); } if (pptr() > pbase()) return overflow(); return 0;}streampos PChannelStreamBuffer::seekoff(streamoff off,#ifdef __MWERKS__ ios::seekdir dir, ios::openmode)#else ios::seek_dir dir, int)#endif{ sync(); if (!channel->IsDescendant(PFile::Class())) return -1; ((PFile *)channel)->SetPosition(off, (PFile::FilePositionOrigin)dir); return ((PFile *)channel)->GetPosition();}PChannel::PChannel() : readTimeout(PMaxTimeInterval), writeTimeout(PMaxTimeInterval){ os_handle = -1; osError = 0; lastError = NoError; lastReadCount = lastWriteCount = 0; init(new PChannelStreamBuffer(this)); Construct();}PChannel::~PChannel(){ flush(); Close(); delete (PChannelStreamBuffer *)rdbuf(); init(NULL);}BOOL PChannel::IsOpen() const{ return os_handle >= 0;}int PChannel::ReadChar(){ BYTE c; BOOL retVal = Read(&c, 1); return (retVal && lastReadCount == 1) ? c : -1;}int PChannel::ReadCharWithTimeout(PTimeInterval & timeout){ SetReadTimeout(timeout); PTimeInterval startTick = PTimer::Tick(); int c; if ((c = ReadChar()) < 0) // Timeout or aborted return -1; timeout -= PTimer::Tick() - startTick; return c;}BOOL PChannel::ReadBlock(void * buf, PINDEX len){ char * ptr = (char *)buf; PINDEX numRead = 0; while (numRead < len && Read(ptr+numRead, len - numRead)) numRead += lastReadCount; lastReadCount = numRead; return lastReadCount == len;}PString PChannel::ReadString(PINDEX len){ PString str; ReadBlock(str.GetPointer(len+1), len); str.SetSize(lastReadCount+1); return str;}BOOL PChannel::WriteString(const PString & str){ const char * ptr = str; PINDEX len = 0, slen = str.GetLength(); while (len < slen && Write(ptr+len, slen - len)) len += lastWriteCount; return len == slen;}BOOL PChannel::ReadAsync(void * buf, PINDEX len){ BOOL retVal = Read(buf, len); OnReadComplete(buf, lastReadCount); return retVal;}void PChannel::OnReadComplete(void *, PINDEX){}BOOL PChannel::WriteChar(int c){ PAssert(c >= 0 && c < 256, PInvalidParameter); char buf = (char)c; return Write(&buf, 1);}BOOL PChannel::WriteAsync(const void * buf, PINDEX len){ BOOL retVal = Write(buf, len); OnWriteComplete(buf, lastWriteCount); return retVal;}void PChannel::OnWriteComplete(const void *, PINDEX){}enum { NextCharEndOfString = -1, NextCharDelay = -2, NextCharSend = -3, NextCharWait = -4};static int HexDigit(char c){ if (!isxdigit(c)) return 0; int hex = c - '0'; if (hex < 10) return hex; hex -= 'A' - '9' - 1; if (hex < 16) return hex; return hex - ('a' - 'A');}static int GetNextChar(const PString & command, PINDEX & pos, PTimeInterval * time = NULL){ int temp; if (command[pos] == '\0') return NextCharEndOfString; if (command[pos] != '\\') return command[pos++]; switch (command[++pos]) { case '\0' : return NextCharEndOfString; case 'a' : // alert (ascii value 7) pos++; return 7; case 'b' : // backspace (ascii value 8) pos++; return 8; case 'f' : // formfeed (ascii value 12) pos++; return 12; case 'n' : // newline (ascii value 10) pos++; return 10; case 'r' : // return (ascii value 13) pos++; return 13; case 't' : // horizontal tab (ascii value 9) pos++; return 9; case 'v' : // vertical tab (ascii value 11) pos++; return 11; case 'x' : // followed by hh where nn is hex number (ascii value 0xhh) if (isxdigit(command[++pos])) { temp = HexDigit(command[pos++]); if (isxdigit(command[pos])) temp += HexDigit(command[pos++]); return temp; } return command[pos]; case 's' : pos++; return NextCharSend; case 'd' : // ns delay for n seconds/milliseconds case 'w' : temp = command[pos] == 'd' ? NextCharDelay : NextCharWait; long milliseconds = 0; while (isdigit(command[++pos])) milliseconds = milliseconds*10 + command[pos] - '0'; if (milliseconds <= 0) milliseconds = 1; if (command[pos] == 'm') pos++; else { milliseconds *= 1000; if (command[pos] == 's') pos++; } if (time != NULL) *time = milliseconds; return temp; } if (command[pos] < '0' || command[pos] > '7') return command[pos++]; // octal number 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -