FX::QPipe Class Reference
[Synchronous i/o devices]

#include <QPipe.h>

Inheritance diagram for FX::QPipe:

Inheritance graph
[legend]

List of all members.


Detailed Description

A named pipe i/o device.

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().

Usage:

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.

Warning:
On both POSIX and Win32, the read side of a pipe is operated in non-blocking mode (to prevent blocks on open or breaking waitForData() on POSIX and to emulate thread cancellation on Win32). You shouldn't ever notice this.

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 FXStringname () 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 FXACLpermissions () 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 FXStreamoperator<< (FXStream &s, QIODevice &i)
FXAPI FXStreamoperator>> (FXStream &s, QIODevice &i)

Member Enumeration Documentation

enum FX::QIODevice::CRLFType [inherited]

The type of CR/LF encoding you want.

Enumerator:
Default  Uses the host OS format.
Unix  Uses ASCII 10 to delimit lines.
MacOS  Uses ASCII 13 to delimit lines.
MSDOS  Uses ASCII 13,10 to delimit lines.

enum FX::QIODevice::UnicodeType [inherited]

The type of unicode translation you want.

Enumerator:
NoTranslation  Performs no translation.
UTF8  Outputs in native UTF-8.
UTF16  Converts between native (UTF-8) and UTF-16 big endian.
UTF16LE  Converts between native (UTF-8) and UTF-16 little endian.
UTF32  Converts between native (UTF-8) and UTF-32 big endian.
UTF32LE  Converts between native (UTF-8) and UTF-32 little endian.


Constructor & Destructor Documentation

FX::QPipe::QPipe ( const FXString name,
bool  isDeepPipe = false 
)

Parameters:
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)
Constructs a pipe referring to name on the local machine


Member Function Documentation

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]

Creates the named pipe so that others can connect to it.

Implements FX::QIODeviceS.

bool FX::QPipe::open ( FXuint  mode = IO_ReadWrite  )  [virtual]

Opens an existing named pipe.

Implements FX::QIODeviceS.

void FX::QPipe::close (  )  [virtual]

Closes the connection.

Implements FX::QIODevice.

void FX::QPipe::flush (  )  [virtual]

Flushes any data currently waiting to be transferred.

Implements FX::QIODevice.

bool FX::QPipe::reset (  ) 

Resets the pipe back to original just opened state.

bool FX::QPipe::atEnd (  )  const [virtual]

Returns true if no more data to be read.

Reimplemented from FX::QIODeviceS.

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]

Does nothing as pipes can't be truncated.

Reimplemented from FX::QIODeviceS.

FXfval FX::QPipe::at (  )  const [virtual]

Returns 0 because pipes don't have a current file pointer.

Reimplemented from FX::QIODeviceS.

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]

Returns the ACL for this device.

Reimplemented from FX::QIODevice.

virtual void FX::QPipe::setPermissions ( const FXACL  )  [virtual]

Sets the ACL for this device.

Reimplemented from FX::QIODevice.

static FXACL FX::QPipe::permissions ( const FXString name  )  [static]

Returns the permissions for the pipe section called name.

static void FX::QPipe::setPermissions ( const FXString name,
const FXACL perms 
) [static]

Sets the permissions for the pipe section called name.

FXuval FX::QPipe::readBlock ( char *  data,
FXuval  maxlen 
) [virtual]

Returns:
The number of bytes read (which may be less than requested)
Parameters:
data Pointer to buffer to receive data
maxlen Maximum number of bytes to read
Reads a block of data from the pipe into the given buffer. Will wait forever until requested amount of data has been read if necessary. Is compatible with thread cancellation in FX::QThread on all platforms.

Implements FX::QIODevice.

FXuval FX::QPipe::writeBlock ( const char *  data,
FXuval  maxlen 
) [virtual]

Returns:
The number of bytes written.
Parameters:
data Pointer to buffer of data to send
maxlen Number of bytes to send
Writes a block of data from the given buffer to the pipe. Normally this will be very fast because pipes have large (4k) queues but if the queue is full then the call will block until there is sufficient space before returning.

Implements FX::QIODevice.

int FX::QPipe::ungetch ( int   )  [virtual]

Tries to unread a character. Unsupported for pipes.

Implements FX::QIODevice.

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.

Warning:
Beware race conditions caused by waiting on i/o devices which can be read asynchronously by other threads
Note:
This is a thread cancellation point

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

See also:
QIODeviceOpenFlags

FXuint FX::QIODevice::state (  )  const [inline, inherited]

Returns the state of this device

See also:
QIODeviceStateFlags

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.


Friends And Related Function Documentation

FXAPI FXStream& operator<< ( FXStream s,
QIODevice i 
) [friend, inherited]

Appends the contents of an i/o device to stream s

Warning:
This operation is not thread-safe

FXAPI FXStream& operator>> ( FXStream s,
QIODevice i 
) [friend, inherited]

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

Warning:
This operation is not thread-safe


The documentation for this class was generated from the following file:

(C) 2002-2008 Niall Douglas. Some parts (C) to assorted authors.
Generated on Fri Jun 13 22:28:23 2008 for TnFOX by doxygen v1.5.6