#include <QPipe.h>
This is one of the oldest pieces of code in my extensions to FOX - it was one of the first classes written for Tornado originally and it is a testament to how API compatible with Qt TnFOX is that very little work had to be done to port it. In fact, the below docs are almost identical too :)
QPipe is a synchronous i/o device like FX:QBlkSocket - in other words, reads from it block until data is available. To avoid this, check atEnd() before reading - however generally, you want it to block because you will have allocated a special thread whose sole purpose is to wait on incoming data and asynchronously do something useful with it. One action could be to post a message to some control in the GUI for example but more likely you'll combine it with FX::FXIPCMsgMonitorBase.
Reads and writes are threadsafe, but you should avoid more than two threads working with the same pipe (the same as more than two processes) because transfers occur in no more than maxAtomicLength() (usually 4096 bytes, but it is system dependent) - so two threads writing at the same time will cause the read data to be mixed blocks of data - which you probably don't want. If you do use a pipe which has more than two users, ensure all data transfers are less than maxAtomicLength(). If you want a pipe with less restrictions and only for intra-process communication, see FX::QLocalPipe. If you need less restrictions across multiple processes, see FX::QBlkSocket (though this is inefficient).
Default security is for FX::FXACLEntity::everything() to have full access. This makes sense as named pipes are generally for inter-process communication - if however it's a private pipe for communication with a known process it makes sense to restrict access to the user running that process at least. Note that until the pipe is opened, permissions() returns what will be applied to the pipe on open() rather than the pipe itself - if you want the latter, use the static method.
Like FX::QMemMap, the pipe name is deleted by its creator on POSIX only (on Windows it lasts until the last thing referring to it closes). If you don't want this, specify IO_DontUnlink in the flags to open().
To use is pretty easy - simply construct one, set its name and have your intended server process call create(). Then have your client process call open(). Reads block (wait indefinitely) until someone connects and sends some data. If you set the isDeepPipe
parameter on creation, extra deep buffers are set if supported by the host operating system.
If a pipe should break unexpectedly, a special informational exception FX::FXConnectionLostException is thrown which has a code of FXEXCEPTION_CONNECTIONLOST. You may or may not at this stage wish to call reset(). For anything more than non-trivial usage, you will need to trap and handle this in order to be handling errors correctly.
If you merely want some unique pipe for communication, use setUnique(). This chooses a randomised name and will retry rerandomised names until it finds one available during create(). Thereafter you can send its unique name (retrieved by name()) to the other process to open(). Note that reset() may rerandomise the name if it something else has claimed that name.
A major portability difference is that on Win32/64, named pipes are fundamentally broken in various minor ways plus must cope with thread cancellation. I originally spent many months getting this code to work around all the problems and make them behave like on Unix as much as possible - however it's possible I've missed some area. Please look at the source of QPipe to get some idea of the problems :(
Due to issues with cancelling overlapped i/o on Windows, close() the pipe from the same thread you last performed a read operation. Failure to do this results in free space corruption in the heap which may or may not have the CRT library throw an assertion when validating the MSVC heap. This bug took me two days to find, so I hope that you won't suffer the same!
Public Types | |
enum | CRLFType { Default, Unix, MacOS, MSDOS } |
enum | UnicodeType { NoTranslation, UTF8, UTF16, UTF16LE, UTF32, UTF32LE } |
typedef FXfval | Offset |
Public Member Functions | |
QPipe (const FXString &name, bool isDeepPipe=false) | |
const FXString & | name () const |
void | setName (const FXString &name) |
bool | isUnique () const |
void | setUnique (bool a) |
bool | create (FXuint mode=IO_ReadWrite) |
bool | open (FXuint mode=IO_ReadWrite) |
void | close () |
void | flush () |
bool | reset () |
bool | atEnd () const |
FXfval | size () const |
void | truncate (FXfval size) |
FXfval | at () const |
bool | at (FXfval newpos) |
virtual const FXACL & | permissions () const |
virtual void | setPermissions (const FXACL &perms) |
FXuval | readBlock (char *data, FXuval maxlen) |
FXuval | writeBlock (const char *data, FXuval maxlen) |
int | ungetch (int) |
FXuval | maxAtomicLength () |
virtual bool | isSynchronous () const |
virtual FXuval | readBlockFrom (char *data, FXuval maxlen, FXfval pos) |
FXuval | readBlockFrom (FXuchar *data, FXuval maxlen, FXfval pos) |
virtual FXuval | writeBlockTo (FXfval pos, const char *data, FXuval maxlen) |
FXuval | writeBlockTo (FXfval pos, const FXuchar *data, FXuval maxlen) |
FXuint | flags () const |
FXuint | mode () const |
FXuint | state () const |
CRLFType | crlfFormat () const |
void | setCRLFFormat (CRLFType type) |
UnicodeType | unicodeTranslation () const |
void | setUnicodeTranslation (UnicodeType type) |
bool | isBuffered () const |
bool | isRaw () const |
bool | isTranslated () const |
bool | isUTF16Translated () const |
bool | isUTF32Translated () const |
bool | isReadable () const |
bool | isWriteable () const |
bool | isWritable () const |
bool | isReadWrite () const |
bool | isClosed () const |
bool | isInactive () const |
bool | isOpen () const |
FXuval | readBlock (FXuchar *data, FXuval maxlen) |
FXuval | writeBlock (const FXuchar *data, FXuval maxlen) |
virtual FXuval | readLine (char *data, FXuval maxlen) |
virtual int | getch () |
virtual int | putch (int c) |
FXfval | shredData (FXfval offset, FXfval len=(FXfval)-1) |
Static Public Member Functions | |
static FXACL | permissions (const FXString &name) |
static void | setPermissions (const FXString &name, const FXACL &perms) |
static bool | waitForData (QIODeviceS **signalled, FXuint no, QIODeviceS **list, FXuint waitfor=FXINFINITE) |
static FXuint | waitForDataMax () throw () |
static UnicodeType | determineUnicodeType (FXuchar *data, FXuval len) throw () |
static FXuval | applyCRLF (FXuchar *FXRESTRICT output, const FXuchar *FXRESTRICT input, FXuval outputlen, FXuval &inputlen, CRLFType crlftype=Default, UnicodeType utftype=NoTranslation) |
static FXuval | removeCRLF (FXuchar *FXRESTRICT output, const FXuchar *FXRESTRICT input, FXuval outputlen, FXuval &inputlen, UnicodeType utftype=NoTranslation) |
Protected Member Functions | |
void | setFlags (int f) |
void | setMode (int m) |
void | setState (int s) |
Protected Attributes | |
FXfval | ioIndex |
Friends | |
class | FXIPCChannel |
class | QChildProcess |
struct | QChildProcessPrivate |
FXAPI FXStream & | operator<< (FXStream &s, QIODevice &i) |
FXAPI FXStream & | operator>> (FXStream &s, QIODevice &i) |
enum FX::QIODevice::CRLFType [inherited] |
enum FX::QIODevice::UnicodeType [inherited] |
The type of unicode translation you want.
FX::QPipe::QPipe | ( | const FXString & | name, | |
bool | isDeepPipe = false | |||
) |
name | Name you wish this pipe to refer to. If null, the pipe is set as anonymous | |
isDeepPipe | True if this pipe has extra-deep buffers (useful when shifting data rapidly is paramount) |
const FXString& FX::QPipe::name | ( | ) | const |
The name of the pipe.
void FX::QPipe::setName | ( | const FXString & | name | ) |
Sets the name of the pipe. Closes the previous pipe name if open before changing the name. Also unsets anonymous.
bool FX::QPipe::isUnique | ( | ) | const [inline] |
Returns true if this pipe is unique.
void FX::QPipe::setUnique | ( | bool | a | ) | [inline] |
Set if you want a unique pipe.
bool FX::QPipe::create | ( | FXuint | mode = IO_ReadWrite |
) | [virtual] |
bool FX::QPipe::open | ( | FXuint | mode = IO_ReadWrite |
) | [virtual] |
void FX::QPipe::close | ( | ) | [virtual] |
void FX::QPipe::flush | ( | ) | [virtual] |
bool FX::QPipe::reset | ( | ) |
Resets the pipe back to original just opened state.
bool FX::QPipe::atEnd | ( | ) | const [virtual] |
FXfval FX::QPipe::size | ( | ) | const [virtual] |
Returns the amount of data waiting to be read. May return ((FXfval)-1) if there is data but it's unknown how much.
Implements FX::QIODevice.
void FX::QPipe::truncate | ( | FXfval | size | ) | [virtual] |
FXfval FX::QPipe::at | ( | ) | const [virtual] |
bool FX::QPipe::at | ( | FXfval | newpos | ) | [virtual] |
Returns false because you can't set the current file pointer on a pipe.
Reimplemented from FX::QIODeviceS.
virtual const FXACL& FX::QPipe::permissions | ( | ) | const [virtual] |
virtual void FX::QPipe::setPermissions | ( | const FXACL & | ) | [virtual] |
Returns the permissions for the pipe section called name.
Sets the permissions for the pipe section called name.
FXuval FX::QPipe::readBlock | ( | char * | data, | |
FXuval | maxlen | |||
) | [virtual] |
data | Pointer to buffer to receive data | |
maxlen | Maximum number of bytes to read |
Implements FX::QIODevice.
FXuval FX::QPipe::writeBlock | ( | const char * | data, | |
FXuval | maxlen | |||
) | [virtual] |
data | Pointer to buffer of data to send | |
maxlen | Number of bytes to send |
Implements FX::QIODevice.
int FX::QPipe::ungetch | ( | int | ) | [virtual] |
FXuval FX::QPipe::maxAtomicLength | ( | ) |
Returns the maximum atomic pipe operation data length. This is the maximum amount of data when can be moved before the move splits into more than one transfer (and thus becomes less efficient)
virtual bool FX::QIODeviceS::isSynchronous | ( | ) | const [inline, virtual, inherited] |
Returns true if this device is a synchronous device.
Reimplemented from FX::QIODevice.
Reimplemented in FX::QSSLDevice.
virtual FXuval FX::QIODeviceS::readBlockFrom | ( | char * | data, | |
FXuval | maxlen, | |||
FXfval | pos | |||
) | [virtual, inherited] |
Default implementation throws an exception.
Implements FX::QIODevice.
Reimplemented in FX::QSSLDevice.
virtual FXuval FX::QIODeviceS::writeBlockTo | ( | FXfval | pos, | |
const char * | data, | |||
FXuval | maxlen | |||
) | [virtual, inherited] |
Default implementation throws an exception.
Implements FX::QIODevice.
Reimplemented in FX::QSSLDevice.
static bool FX::QIODeviceS::waitForData | ( | QIODeviceS ** | signalled, | |
FXuint | no, | |||
QIODeviceS ** | list, | |||
FXuint | waitfor = FXINFINITE | |||
) | [static, inherited] |
Waits for more data to become available for reading on any one or more of an array of QIODeviceS's specified by list. Precisely which are those left in the array signalled if it's not NULL with empty members being zero.
static FXuint FX::QIODeviceS::waitForDataMax | ( | ) | throw () [static, inherited] |
Returns the maximum number of QIODeviceS's which can be waited for at once.
FXuint FX::QIODevice::flags | ( | ) | const [inline, inherited] |
Returns the flags of this device.
FXuint FX::QIODevice::mode | ( | ) | const [inline, inherited] |
Returns the mode of this device
FXuint FX::QIODevice::state | ( | ) | const [inline, inherited] |
Returns the state of this device
CRLFType FX::QIODevice::crlfFormat | ( | ) | const [inline, inherited] |
Returns the CR/LF format of this device.
void FX::QIODevice::setCRLFFormat | ( | CRLFType | type | ) | [inline, inherited] |
Sets the CR/LF format for output of this device.
UnicodeType FX::QIODevice::unicodeTranslation | ( | ) | const [inline, inherited] |
Returns the unicode translation of this device.
void FX::QIODevice::setUnicodeTranslation | ( | UnicodeType | type | ) | [inline, inherited] |
Sets the unicode translation of this device.
bool FX::QIODevice::isBuffered | ( | ) | const [inline, inherited] |
Returns true if the device is buffered.
bool FX::QIODevice::isRaw | ( | ) | const [inline, inherited] |
Returns true if the device is unbuffered.
bool FX::QIODevice::isTranslated | ( | ) | const [inline, inherited] |
Returns true if the device is LR/CF translated.
bool FX::QIODevice::isUTF16Translated | ( | ) | const [inline, inherited] |
Returns true if the device is UTF-16 translated.
bool FX::QIODevice::isUTF32Translated | ( | ) | const [inline, inherited] |
Returns true if the device is UTF-32 translated.
bool FX::QIODevice::isReadable | ( | ) | const [inline, inherited] |
Returns true if the device is readable.
bool FX::QIODevice::isWriteable | ( | ) | const [inline, inherited] |
Returns true if the device is writeable.
bool FX::QIODevice::isReadWrite | ( | ) | const [inline, inherited] |
Returns true if the device is readable & writeable.
bool FX::QIODevice::isClosed | ( | ) | const [inline, inherited] |
Returns true if the device is closed.
bool FX::QIODevice::isOpen | ( | ) | const [inline, inherited] |
Returns true if the device is opened.
virtual FXuval FX::QIODevice::readLine | ( | char * | data, | |
FXuval | maxlen | |||
) | [virtual, inherited] |
Reads data until an end-of-line or maxlen is exceeded.
virtual int FX::QIODevice::getch | ( | ) | [virtual, inherited] |
Reads a single byte. Returns -1 for no data found.
Reimplemented in FX::QBuffer, FX::QBZip2Device, FX::QGZipDevice, and FX::QMemMap.
virtual int FX::QIODevice::putch | ( | int | c | ) | [virtual, inherited] |
Writes a single byte.
Reimplemented in FX::QBuffer, FX::QBZip2Device, FX::QGZipDevice, and FX::QMemMap.
static UnicodeType FX::QIODevice::determineUnicodeType | ( | FXuchar * | data, | |
FXuval | len | |||
) | throw () [static, inherited] |
Looks at a sample of data and determines what kind of Unicode text it is, returning UnicodeType::NoTranslation if it isn't text. This routine isn't foolproof, but it's a good guess
static FXuval FX::QIODevice::applyCRLF | ( | FXuchar *FXRESTRICT | output, | |
const FXuchar *FXRESTRICT | input, | |||
FXuval | outputlen, | |||
FXuval & | inputlen, | |||
CRLFType | crlftype = Default , |
|||
UnicodeType | utftype = NoTranslation | |||
) | [static, inherited] |
Applies CR/LF and optional UTF-x translation returning bytes output. If outputlen would run out before inputlen can be exhausted it will return early (eg; if mid newline, or mid UTF-x sequence). You should rewind processing to the difference between entrant inputlen and returned inputlen.
static FXuval FX::QIODevice::removeCRLF | ( | FXuchar *FXRESTRICT | output, | |
const FXuchar *FXRESTRICT | input, | |||
FXuval | outputlen, | |||
FXuval & | inputlen, | |||
UnicodeType | utftype = NoTranslation | |||
) | [static, inherited] |
Removes CR/LF translation intelligently (ie; self-adjusts to MS-DOS, Unix and MacOS formats or any mixture of these) and can perform optional UTF-x translation, returning bytes output. If outputlen would run out before inputlen can be exhausted it will return early (eg; if mid newline, or mid UTF-x sequence). You should rewind processing to the difference between entrant inputlen and returned inputlen.
FXfval FX::QIODevice::shredData | ( | FXfval | offset, | |
FXfval | len = (FXfval)-1 | |||
) | [inherited] |
Destroys the len bytes of data from offset offset into the file. Restores the file pointer afterwards and returns how much data was shredded before end of file if encountered. You must have the device open for both reading and writing for this call to succeed.
void FX::QIODevice::setFlags | ( | int | f | ) | [inline, protected, inherited] |
Sets the flags.
void FX::QIODevice::setMode | ( | int | m | ) | [inline, protected, inherited] |
Sets the mode.
void FX::QIODevice::setState | ( | int | s | ) | [inline, protected, inherited] |
Sets the state.
Appends the contents of an i/o device to stream s
Reads all available contents of the stream s to an i/o device, replacing its current contents and resetting the file pointer to the start