tclIO.h
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:17k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* 
  2.  * tclIO.h --
  3.  *
  4.  * This file provides the generic portions (those that are the same on
  5.  * all platforms and for all channel types) of Tcl's IO facilities.
  6.  *
  7.  * Copyright (c) 1998-2000 Ajuba Solutions
  8.  * Copyright (c) 1995-1997 Sun Microsystems, Inc.
  9.  *
  10.  * See the file "license.terms" for information on usage and redistribution
  11.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  12.  *
  13.  * RCS: @(#) $Id: tclIO.h,v 1.5.4.2 2004/07/15 20:46:19 andreas_kupries Exp $
  14.  */
  15. /*
  16.  * Make sure that both EAGAIN and EWOULDBLOCK are defined. This does not
  17.  * compile on systems where neither is defined. We want both defined so
  18.  * that we can test safely for both. In the code we still have to test for
  19.  * both because there may be systems on which both are defined and have
  20.  * different values.
  21.  */
  22. #if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN)))
  23. #   define EWOULDBLOCK EAGAIN
  24. #endif
  25. #if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK)))
  26. #   define EAGAIN EWOULDBLOCK
  27. #endif
  28. #if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK)))
  29. error one of EWOULDBLOCK or EAGAIN must be defined
  30. #endif
  31. /*
  32.  * The following structure encapsulates the state for a background channel
  33.  * copy.  Note that the data buffer for the copy will be appended to this
  34.  * structure.
  35.  */
  36. typedef struct CopyState {
  37.     struct Channel *readPtr; /* Pointer to input channel. */
  38.     struct Channel *writePtr; /* Pointer to output channel. */
  39.     int readFlags; /* Original read channel flags. */
  40.     int writeFlags; /* Original write channel flags. */
  41.     int toRead; /* Number of bytes to copy, or -1. */
  42.     int total; /* Total bytes transferred (written). */
  43.     Tcl_Interp *interp; /* Interp that started the copy. */
  44.     Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */
  45.     int bufSize; /* Size of appended buffer. */
  46.     char buffer[1]; /* Copy buffer, this must be the last
  47.  * field. */
  48. } CopyState;
  49. /*
  50.  * struct ChannelBuffer:
  51.  *
  52.  * Buffers data being sent to or from a channel.
  53.  */
  54. typedef struct ChannelBuffer {
  55.     int nextAdded; /* The next position into which a character
  56.                                  * will be put in the buffer. */
  57.     int nextRemoved; /* Position of next byte to be removed
  58.                                  * from the buffer. */
  59.     int bufLength; /* How big is the buffer? */
  60.     struct ChannelBuffer *nextPtr;
  61.      /* Next buffer in chain. */
  62.     char buf[4]; /* Placeholder for real buffer. The real
  63.                                  * buffer occuppies this space + bufSize-4
  64.                                  * bytes. This must be the last field in
  65.                                  * the structure. */
  66. } ChannelBuffer;
  67. #define CHANNELBUFFER_HEADER_SIZE (sizeof(ChannelBuffer) - 4)
  68. /*
  69.  * How much extra space to allocate in buffer to hold bytes from previous
  70.  * buffer (when converting to UTF-8) or to hold bytes that will go to
  71.  * next buffer (when converting from UTF-8).
  72.  */
  73.  
  74. #define BUFFER_PADDING     16
  75.  
  76. /*
  77.  * The following defines the *default* buffer size for channels.
  78.  */
  79. #define CHANNELBUFFER_DEFAULT_SIZE (1024 * 4)
  80. /*
  81.  * Structure to record a close callback. One such record exists for
  82.  * each close callback registered for a channel.
  83.  */
  84. typedef struct CloseCallback {
  85.     Tcl_CloseProc *proc; /* The procedure to call. */
  86.     ClientData clientData; /* Arbitrary one-word data to pass
  87.  * to the callback. */
  88.     struct CloseCallback *nextPtr; /* For chaining close callbacks. */
  89. } CloseCallback;
  90. /*
  91.  * The following structure describes the information saved from a call to
  92.  * "fileevent". This is used later when the event being waited for to
  93.  * invoke the saved script in the interpreter designed in this record.
  94.  */
  95. typedef struct EventScriptRecord {
  96.     struct Channel *chanPtr; /* The channel for which this script is
  97.  * registered. This is used only when an
  98.  * error occurs during evaluation of the
  99.  * script, to delete the handler. */
  100.     Tcl_Obj *scriptPtr; /* Script to invoke. */
  101.     Tcl_Interp *interp; /* In what interpreter to invoke script? */
  102.     int mask; /* Events must overlap current mask for the
  103.  * stored script to be invoked. */
  104.     struct EventScriptRecord *nextPtr;
  105. /* Next in chain of records. */
  106. } EventScriptRecord;
  107. /*
  108.  * struct Channel:
  109.  *
  110.  * One of these structures is allocated for each open channel. It contains data
  111.  * specific to the channel but which belongs to the generic part of the Tcl
  112.  * channel mechanism, and it points at an instance specific (and type
  113.  * specific) * instance data, and at a channel type structure.
  114.  */
  115. typedef struct Channel {
  116.     struct ChannelState *state; /* Split out state information */
  117.     ClientData instanceData; /* Instance-specific data provided by
  118.  * creator of channel. */
  119.     Tcl_ChannelType *typePtr; /* Pointer to channel type structure. */
  120.     struct Channel *downChanPtr;/* Refers to channel this one was stacked
  121.  * upon.  This reference is NULL for normal
  122.  * channels.  See Tcl_StackChannel. */
  123.     struct Channel *upChanPtr; /* Refers to the channel above stacked this
  124.  * one. NULL for the top most channel. */
  125.     /*
  126.      * Intermediate buffers to hold pre-read data for consumption by a
  127.      * newly stacked transformation. See 'Tcl_StackChannel'.
  128.      */
  129.     ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */
  130.     ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */
  131. } Channel;
  132. /*
  133.  * struct ChannelState:
  134.  *
  135.  * One of these structures is allocated for each open channel. It contains data
  136.  * specific to the channel but which belongs to the generic part of the Tcl
  137.  * channel mechanism, and it points at an instance specific (and type
  138.  * specific) * instance data, and at a channel type structure.
  139.  */
  140. typedef struct ChannelState {
  141.     CONST char *channelName; /* The name of the channel instance in Tcl
  142.  * commands. Storage is owned by the generic IO
  143.  * code, is dynamically allocated. */
  144.     int flags; /* ORed combination of the flags defined
  145.  * below. */
  146.     Tcl_Encoding encoding; /* Encoding to apply when reading or writing
  147.  * data on this channel.  NULL means no
  148.  * encoding is applied to data. */
  149.     Tcl_EncodingState inputEncodingState;
  150. /* Current encoding state, used when converting
  151.  * input data bytes to UTF-8. */
  152.     int inputEncodingFlags; /* Encoding flags to pass to conversion
  153.  * routine when converting input data bytes to
  154.  * UTF-8.  May be TCL_ENCODING_START before
  155.  * converting first byte and TCL_ENCODING_END
  156.  * when EOF is seen. */
  157.     Tcl_EncodingState outputEncodingState;
  158. /* Current encoding state, used when converting
  159.  * UTF-8 to output data bytes. */
  160.     int outputEncodingFlags; /* Encoding flags to pass to conversion
  161.  * routine when converting UTF-8 to output
  162.  * data bytes.  May be TCL_ENCODING_START
  163.  * before converting first byte and
  164.  * TCL_ENCODING_END when EOF is seen. */
  165.     TclEolTranslation inputTranslation;
  166. /* What translation to apply for end of line
  167.  * sequences on input? */    
  168.     TclEolTranslation outputTranslation;
  169. /* What translation to use for generating
  170.  * end of line sequences in output? */
  171.     int inEofChar; /* If nonzero, use this as a signal of EOF
  172.  * on input. */
  173.     int outEofChar;             /* If nonzero, append this to the channel
  174.  * when it is closed if it is open for
  175.  * writing. */
  176.     int unreportedError; /* Non-zero if an error report was deferred
  177.  * because it happened in the background. The
  178.  * value is the POSIX error code. */
  179.     int refCount; /* How many interpreters hold references to
  180.  * this IO channel? */
  181.     CloseCallback *closeCbPtr; /* Callbacks registered to be called when the
  182.  * channel is closed. */
  183.     char *outputStage; /* Temporary staging buffer used when
  184.  * translating EOL before converting from
  185.  * UTF-8 to external form. */
  186.     ChannelBuffer *curOutPtr; /* Current output buffer being filled. */
  187.     ChannelBuffer *outQueueHead;/* Points at first buffer in output queue. */
  188.     ChannelBuffer *outQueueTail;/* Points at last buffer in output queue. */
  189.     ChannelBuffer *saveInBufPtr;/* Buffer saved for input queue - eliminates
  190.  * need to allocate a new buffer for "gets"
  191.  * that crosses buffer boundaries. */
  192.     ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */
  193.     ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */
  194.     struct ChannelHandler *chPtr;/* List of channel handlers registered
  195.   * for this channel. */
  196.     int interestMask; /* Mask of all events this channel has
  197.  * handlers for. */
  198.     EventScriptRecord *scriptRecordPtr;
  199. /* Chain of all scripts registered for
  200.  * event handlers ("fileevent") on this
  201.  * channel. */
  202.     int bufSize; /* What size buffers to allocate? */
  203.     Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */
  204.     CopyState *csPtr; /* State of background copy, or NULL. */
  205.     Channel *topChanPtr; /* Refers to topmost channel in a stack.
  206.  * Never NULL. */
  207.     Channel *bottomChanPtr; /* Refers to bottommost channel in a stack.
  208.  * This channel can be relied on to live as
  209.  * long as the channel state. Never NULL. */
  210.     struct ChannelState *nextCSPtr;
  211. /* Next in list of channels currently open. */
  212.     Tcl_ThreadId managingThread; /* TIP #10: Id of the thread managing
  213.   * this stack of channels. */
  214. } ChannelState;
  215.     
  216. /*
  217.  * Values for the flags field in Channel. Any ORed combination of the
  218.  * following flags can be stored in the field. These flags record various
  219.  * options and state bits about the channel. In addition to the flags below,
  220.  * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set.
  221.  */
  222. #define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in
  223.  * nonblocking mode. */
  224. #define CHANNEL_LINEBUFFERED (1<<4) /* Output to the channel must be
  225.  * flushed after every newline. */
  226. #define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always
  227.  * be flushed immediately. */
  228. #define BUFFER_READY (1<<6) /* Current output buffer (the
  229.  * curOutPtr field in the
  230.                                          * channel structure) should be
  231.                                          * output as soon as possible even
  232.                                          * though it may not be full. */
  233. #define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the
  234.  * queued output buffers has been
  235.                                          * scheduled. */
  236. #define CHANNEL_CLOSED (1<<8) /* Channel has been closed. No
  237.  * further Tcl-level IO on the
  238.                                          * channel is allowed. */
  239. #define CHANNEL_EOF (1<<9) /* EOF occurred on this channel.
  240.  * This bit is cleared before every
  241.                                          * input operation. */
  242. #define CHANNEL_STICKY_EOF (1<<10) /* EOF occurred on this channel because
  243.  * we saw the input eofChar. This bit
  244.                                          * prevents clearing of the EOF bit
  245.                                          * before every input operation. */
  246. #define CHANNEL_BLOCKED (1<<11) /* EWOULDBLOCK or EAGAIN occurred
  247.  * on this channel. This bit is
  248.  * cleared before every input or
  249.  * output operation. */
  250. #define INPUT_SAW_CR (1<<12) /* Channel is in CRLF eol input
  251.  * translation mode and the last
  252.                                          * byte seen was a "r". */
  253. #define INPUT_NEED_NL (1<<15) /* Saw a 'r' at end of last buffer,
  254.  * and there should be a 'n' at
  255.  * beginning of next buffer. */
  256. #define CHANNEL_DEAD (1<<13) /* The channel has been closed by
  257.  * the exit handler (on exit) but
  258.                                          * not deallocated. When any IO
  259.                                          * operation sees this flag on a
  260.                                          * channel, it does not call driver
  261.                                          * level functions to avoid referring
  262.                                          * to deallocated data. */
  263. #define CHANNEL_NEED_MORE_DATA (1<<14) /* The last input operation failed
  264.  * because there was not enough data
  265.  * to complete the operation.  This
  266.  * flag is set when gets fails to
  267.  * get a complete line or when read
  268.  * fails to get a complete character.
  269.  * When set, file events will not be
  270.  * delivered for buffered data until
  271.  * the state of the channel changes. */
  272. #define CHANNEL_RAW_MODE (1<<16) /* When set, notes that the Raw API is
  273.  * being used. */
  274. #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
  275. #define CHANNEL_TIMER_FEV       (1<<17) /* When set the event we are
  276.  * notified by is a fileevent
  277.  * generated by a timer. We
  278.  * don't know if the driver
  279.  * has more data and should
  280.  * not try to read from it. If
  281.  * the system needs more than
  282.  * is in the buffers out read
  283.  * routines will simulate a
  284.  * short read (0 characters
  285.  * read) */
  286. #define CHANNEL_HAS_MORE_DATA   (1<<18) /* Set by NotifyChannel for a
  287.  * channel if and only if the
  288.  * channel is configured
  289.  * non-blocking, the driver
  290.  * for said channel has no
  291.  * blockmodeproc, and data has
  292.  * arrived for reading at the
  293.  * OS level). A GetInput will
  294.  * pass reading from the
  295.  * driver if the channel is
  296.  * non-blocking, without
  297.  * blockmode proc and the flag
  298.  * has not been set. A read
  299.  * will be performed if the
  300.  * flag is set. This will
  301.  * reset the flag as well. */
  302. #endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
  303. #define CHANNEL_INCLOSE (1<<19) /* Channel is currently being
  304.  * closed. Its structures are
  305.  * still live and usable, but
  306.  * it may not be closed again
  307.  * from within the close handler.
  308.  */
  309. /*
  310.  * For each channel handler registered in a call to Tcl_CreateChannelHandler,
  311.  * there is one record of the following type. All of records for a specific
  312.  * channel are chained together in a singly linked list which is stored in
  313.  * the channel structure.
  314.  */
  315. typedef struct ChannelHandler {
  316.     Channel *chanPtr; /* The channel structure for this channel. */
  317.     int mask; /* Mask of desired events. */
  318.     Tcl_ChannelProc *proc; /* Procedure to call in the type of
  319.                                  * Tcl_CreateChannelHandler. */
  320.     ClientData clientData; /* Argument to pass to procedure. */
  321.     struct ChannelHandler *nextPtr;
  322.      /* Next one in list of registered handlers. */
  323. } ChannelHandler;
  324. /*
  325.  * This structure keeps track of the current ChannelHandler being invoked in
  326.  * the current invocation of ChannelHandlerEventProc. There is a potential
  327.  * problem if a ChannelHandler is deleted while it is the current one, since
  328.  * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this
  329.  * problem, structures of the type below indicate the next handler to be
  330.  * processed for any (recursively nested) dispatches in progress. The
  331.  * nextHandlerPtr field is updated if the handler being pointed to is deleted.
  332.  * The nextPtr field is used to chain together all recursive invocations, so
  333.  * that Tcl_DeleteChannelHandler can find all the recursively nested
  334.  * invocations of ChannelHandlerEventProc and compare the handler being
  335.  * deleted against the NEXT handler to be invoked in that invocation; when it
  336.  * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr
  337.  * field of the structure to the next handler.
  338.  */
  339. typedef struct NextChannelHandler {
  340.     ChannelHandler *nextHandlerPtr; /* The next handler to be invoked in
  341.                                          * this invocation. */
  342.     struct NextChannelHandler *nestedHandlerPtr;
  343.     /* Next nested invocation of
  344.      * ChannelHandlerEventProc. */
  345. } NextChannelHandler;
  346. /*
  347.  * The following structure describes the event that is added to the Tcl
  348.  * event queue by the channel handler check procedure.
  349.  */
  350. typedef struct ChannelHandlerEvent {
  351.     Tcl_Event header; /* Standard header for all events. */
  352.     Channel *chanPtr; /* The channel that is ready. */
  353.     int readyMask; /* Events that have occurred. */
  354. } ChannelHandlerEvent;
  355. /*
  356.  * The following structure is used by Tcl_GetsObj() to encapsulates the
  357.  * state for a "gets" operation.
  358.  */
  359.  
  360. typedef struct GetsState {
  361.     Tcl_Obj *objPtr; /* The object to which UTF-8 characters
  362.  * will be appended. */
  363.     char **dstPtr; /* Pointer into objPtr's string rep where
  364.  * next character should be stored. */
  365.     Tcl_Encoding encoding; /* The encoding to use to convert raw bytes
  366.  * to UTF-8.  */
  367.     ChannelBuffer *bufPtr; /* The current buffer of raw bytes being
  368.  * emptied. */
  369.     Tcl_EncodingState state; /* The encoding state just before the last
  370.  * external to UTF-8 conversion in
  371.  * FilterInputBytes(). */
  372.     int rawRead; /* The number of bytes removed from bufPtr
  373.  * in the last call to FilterInputBytes(). */
  374.     int bytesWrote; /* The number of bytes of UTF-8 data
  375.  * appended to objPtr during the last call to
  376.  * FilterInputBytes(). */
  377.     int charsWrote; /* The corresponding number of UTF-8
  378.  * characters appended to objPtr during the
  379.  * last call to FilterInputBytes(). */
  380.     int totalChars; /* The total number of UTF-8 characters
  381.  * appended to objPtr so far, just before the
  382.  * last call to FilterInputBytes(). */
  383. } GetsState;