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