Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Eliminate the use of a staging buffer in WriteChars(). |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
f5f5df0f00d4215aea8eb071f3bea8d5 |
User & Date: | dgp 2014-01-30 14:51:44 |
Context
2014-01-31
| ||
09:19 | Fix [4b3b7a3082]: tcl8.5.15/generic/tclExecute.c:7713: array index before sanity check ? check-in: 0b5fb73910 user: jan.nijtmans tags: trunk | |
2014-01-30
| ||
16:21 | merge trunk check-in: b05a6048ea user: dgp tags: dgp-refactor | |
14:51 | Eliminate the use of a staging buffer in WriteChars(). check-in: f5f5df0f00 user: dgp tags: trunk | |
14:50 | Fix [22c10c8e79]: core-8-5: msvc6 build: "Side by Side" error check-in: 3fb17c9267 user: jan.nijtmans tags: trunk | |
14:31 | Eliminate the use of a staging buffer in WriteChars(). check-in: 4749538620 user: dgp tags: core-8-5-branch | |
Changes
Changes to generic/tclIO.c.
︙ | ︙ | |||
1577 1578 1579 1580 1581 1582 1583 | statePtr->chPtr = NULL; statePtr->interestMask = 0; statePtr->scriptRecordPtr = NULL; statePtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE; statePtr->timer = NULL; statePtr->csPtrR = NULL; statePtr->csPtrW = NULL; | < < < < | 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 | statePtr->chPtr = NULL; statePtr->interestMask = 0; statePtr->scriptRecordPtr = NULL; statePtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE; statePtr->timer = NULL; statePtr->csPtrR = NULL; statePtr->csPtrW = NULL; statePtr->outputStage = NULL; /* * As we are creating the channel, it is obviously the top for now. */ statePtr->topChanPtr = chanPtr; statePtr->bottomChanPtr = chanPtr; |
︙ | ︙ | |||
2834 2835 2836 2837 2838 2839 2840 | if (chanPtr == statePtr->bottomChanPtr) { if (statePtr->channelName != NULL) { ckfree(statePtr->channelName); statePtr->channelName = NULL; } Tcl_FreeEncoding(statePtr->encoding); | < < < < | 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 | if (chanPtr == statePtr->bottomChanPtr) { if (statePtr->channelName != NULL) { ckfree(statePtr->channelName); statePtr->channelName = NULL; } Tcl_FreeEncoding(statePtr->encoding); } /* * If we are being called synchronously, report either any latent error on * the channel or the current error. */ |
︙ | ︙ | |||
4159 4160 4161 4162 4163 4164 4165 | WriteChars( Channel *chanPtr, /* The channel to buffer output for. */ const char *src, /* UTF-8 string to write. */ int srcLen) /* Length of UTF-8 string in bytes. */ { ChannelState *statePtr = chanPtr->state; /* State info for channel */ | < | < | < | < < < < < < < | | | < < < < | < < < < < < | | < < < < | < < < < < < < | < < < | < < < < | < < < | < < < | < < < < | < < | < < < < < < | | | | | < < < | | | | | | | < < | | > > | | | | | | < | > | | | | < > | > | < | > > > > > | > > > > | > > > > > > > > > > > > > > > > | > > | > > < < < > > | < < < < < < > | | > > | > | < | | | | | | | | | | | | | | < < | | < < < | | < < | < > | < | > | | > > > > > | < < < < | < < < | | 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 | WriteChars( Channel *chanPtr, /* The channel to buffer output for. */ const char *src, /* UTF-8 string to write. */ int srcLen) /* Length of UTF-8 string in bytes. */ { ChannelState *statePtr = chanPtr->state; /* State info for channel */ char *nextNewLine = NULL; int endEncoding, saved = 0, total = 0, flushed = 0, needNlFlush = 0; Tcl_Encoding encoding = statePtr->encoding; if (srcLen) { WillWrite(chanPtr); } /* * Write the terminated escape sequence even if srcLen is 0. */ endEncoding = ((statePtr->outputEncodingFlags & TCL_ENCODING_END) != 0); if (GotFlag(statePtr, CHANNEL_LINEBUFFERED) || (statePtr->outputTranslation != TCL_TRANSLATE_LF)) { nextNewLine = memchr(src, '\n', srcLen); } while (srcLen + saved + endEncoding > 0) { ChannelBuffer *bufPtr; char *dst, safe[BUFFER_PADDING]; int result, srcRead, dstLen, dstWrote, srcLimit = srcLen; if (nextNewLine) { srcLimit = nextNewLine - src; } /* Get space to write into */ bufPtr = statePtr->curOutPtr; if (bufPtr == NULL) { bufPtr = AllocChannelBuffer(statePtr->bufSize); statePtr->curOutPtr = bufPtr; } if (saved) { /* * Here's some translated bytes left over from the last buffer * that we need to stick at the beginning of this buffer. */ memcpy(InsertPoint(bufPtr), safe, (size_t) saved); bufPtr->nextAdded += saved; saved = 0; } dst = InsertPoint(bufPtr); dstLen = SpaceLeft(bufPtr); result = Tcl_UtfToExternal(NULL, encoding, src, srcLimit, statePtr->outputEncodingFlags, &statePtr->outputEncodingState, dst, dstLen + BUFFER_PADDING, &srcRead, &dstWrote, NULL); /* See chan-io-1.[89]. Tcl Bug 506297. */ statePtr->outputEncodingFlags &= ~TCL_ENCODING_START; if ((result != TCL_OK) && (srcRead + dstWrote == 0)) { /* We're reading from invalid/incomplete UTF-8 */ if (total == 0) { Tcl_SetErrno(EINVAL); return -1; } break; } bufPtr->nextAdded += dstWrote; src += srcRead; srcLen -= srcRead; total += dstWrote; dst += dstWrote; dstLen -= dstWrote; if (src == nextNewLine && dstLen > 0) { static char crln[3] = "\r\n"; char *nl = NULL; int nlLen = 0; switch (statePtr->outputTranslation) { case TCL_TRANSLATE_LF: nl = crln + 1; nlLen = 1; break; case TCL_TRANSLATE_CR: nl = crln; nlLen = 1; break; case TCL_TRANSLATE_CRLF: nl = crln; nlLen = 2; break; default: Tcl_Panic("unknown output translation requested"); break; } result |= Tcl_UtfToExternal(NULL, encoding, nl, nlLen, statePtr->outputEncodingFlags, &statePtr->outputEncodingState, dst, dstLen + BUFFER_PADDING, &srcRead, &dstWrote, NULL); if (srcRead != nlLen) { Tcl_Panic("Can This Happen?"); } bufPtr->nextAdded += dstWrote; src++; srcLen--; total += dstWrote; dst += dstWrote; dstLen -= dstWrote; nextNewLine = memchr(src, '\n', srcLen); needNlFlush = 1; } if (IsBufferOverflowing(bufPtr)) { /* * When translating from UTF-8 to external encoding, we * allowed the translation to produce a character that crossed * the end of the output buffer, so that we would get a * completely full buffer before flushing it. The extra bytes * will be moved to the beginning of the next buffer. */ saved = -SpaceLeft(bufPtr); memcpy(safe, dst + dstLen, (size_t) saved); bufPtr->nextAdded = bufPtr->bufLength; } if ((srcLen + saved == 0) && (result == TCL_OK)) { endEncoding = 0; } if (IsBufferFull(bufPtr)) { if (FlushChannel(NULL, chanPtr, 0) != 0) { return -1; } flushed += statePtr->bufSize; if (saved == 0 || src[-1] != '\n') { needNlFlush = 0; } } } if ((flushed < total) && (GotFlag(statePtr, CHANNEL_UNBUFFERED) || (needNlFlush && GotFlag(statePtr, CHANNEL_LINEBUFFERED)))) { SetFlag(statePtr, BUFFER_READY); if (FlushChannel(NULL, chanPtr, 0) != 0) { return -1; } } return total; } /* *--------------------------------------------------------------------------- * * TranslateOutputEOL -- |
︙ | ︙ | |||
7592 7593 7594 7595 7596 7597 7598 | sz = 1; } else if (sz > MAX_CHANNEL_BUFFER_SIZE) { sz = MAX_CHANNEL_BUFFER_SIZE; } statePtr = ((Channel *) chan)->state; statePtr->bufSize = sz; | < < < < < < < < | 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 | sz = 1; } else if (sz > MAX_CHANNEL_BUFFER_SIZE) { sz = MAX_CHANNEL_BUFFER_SIZE; } statePtr = ((Channel *) chan)->state; statePtr->bufSize = sz; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelBufferSize -- * |
︙ | ︙ | |||
8240 8241 8242 8243 8244 8245 8246 | && (statePtr->inQueueHead->nextPtr == NULL) && IsBufferEmpty(statePtr->inQueueHead)) { RecycleBuffer(statePtr, statePtr->inQueueHead, 1); statePtr->inQueueHead = NULL; statePtr->inQueueTail = NULL; } | < < < < < < < < < < < | 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 | && (statePtr->inQueueHead->nextPtr == NULL) && IsBufferEmpty(statePtr->inQueueHead)) { RecycleBuffer(statePtr, statePtr->inQueueHead, 1); statePtr->inQueueHead = NULL; statePtr->inQueueTail = NULL; } return TCL_OK; } /* *---------------------------------------------------------------------- * * CleanupChannelHandlers -- |
︙ | ︙ |