diff options
author | dgp <dgp@users.sourceforge.net> | 2014-08-21 04:13:35 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2014-08-21 04:13:35 (GMT) |
commit | f8aafabe46ed2181ab3fe95bc136918c3cdfa648 (patch) | |
tree | 5592b6a8c33cda45832b373d03889b532eb410d5 | |
parent | 32380b152911ac426b039bff40279187994bdca0 (diff) | |
download | tcl-dgp_writebytes_optimize.zip tcl-dgp_writebytes_optimize.tar.gz tcl-dgp_writebytes_optimize.tar.bz2 |
Make simplificiations possible when we know just bytes are getting copieddgp_writebytes_optimize
without complications of encodings
-rw-r--r-- | generic/tclIO.c | 98 |
1 files changed, 29 insertions, 69 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index 7885eab..03849fb 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -228,8 +228,6 @@ static int WillRead(Channel *chanPtr); #define WriteChars(chanPtr, src, srcLen) \ Write(chanPtr, src, srcLen, chanPtr->state->encoding) -//#define WriteBytes(chanPtr, src, srcLen) \ -// Write(chanPtr, src, srcLen, tclIdentityEncoding) static int WriteBytes(Channel *chanPtr, const char *src, int srcLen); @@ -3899,30 +3897,22 @@ WriteBytes( { ChannelState *statePtr = chanPtr->state; /* State info for channel */ - Tcl_Encoding encoding = tclIdentityEncoding; - char *nextNewLine = NULL; - int endEncoding, saved = 0, total = 0, flushed = 0, needNlFlush = 0; + int saved = 0, total = 0, flushed = 0, needNlFlush = 0; 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) { + while (srcLen + saved > 0) { ChannelBuffer *bufPtr; - char *dst, safe[BUFFER_PADDING]; - int result, srcRead, dstLen, dstWrote, srcLimit = srcLen; + char *dst; + int dstLen, srcLimit = srcLen; if (nextNewLine) { srcLimit = nextNewLine - src; @@ -3935,43 +3925,30 @@ WriteBytes( 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; + /* Start new buffer with \n straddled over from last one */ + InsertPoint(bufPtr)[0] = '\n'; + bufPtr->nextAdded++; saved = 0; + needNlFlush = 1; } PreserveChannelBuffer(bufPtr); 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 */ - ReleaseChannelBuffer(bufPtr); - if (total == 0) { - Tcl_SetErrno(EINVAL); - return -1; - } - break; + if (srcLimit < 0) { + srcLimit = strlen(src); + } + if (srcLimit > dstLen) { + srcLimit = dstLen; } + memcpy(dst, src, (size_t) srcLimit); - bufPtr->nextAdded += dstWrote; - src += srcRead; - srcLen -= srcRead; - total += dstWrote; - dst += dstWrote; - dstLen -= dstWrote; + bufPtr->nextAdded += srcLimit; + src += srcLimit; + srcLen -= srcLimit; + total += srcLimit; + dst += srcLimit; + dstLen -= srcLimit; if (src == nextNewLine && dstLen > 0) { static char crln[3] = "\r\n"; @@ -3995,51 +3972,34 @@ WriteBytes( 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); - assert (srcRead == nlLen); + memcpy(dst, nl, (size_t) nlLen); - bufPtr->nextAdded += dstWrote; + bufPtr->nextAdded += nlLen; src++; srcLen--; - total += dstWrote; - dst += dstWrote; - dstLen -= dstWrote; + total += nlLen; + dst += nlLen; + dstLen -= nlLen; 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. - */ + /* Can only happend when \r\n straddles buffers */ - saved = -SpaceLeft(bufPtr); - memcpy(safe, dst + dstLen, (size_t) saved); + saved = 1; bufPtr->nextAdded = bufPtr->bufLength; } - if ((srcLen + saved == 0) && (result == TCL_OK)) { - endEncoding = 0; - } - if (IsBufferFull(bufPtr)) { if (FlushChannel(NULL, chanPtr, 0) != 0) { ReleaseChannelBuffer(bufPtr); return -1; } + /* TODO: ought to add bytes actually flushed */ flushed += statePtr->bufSize; - if (saved == 0 || src[-1] != '\n') { - needNlFlush = 0; - } + needNlFlush = 0; } ReleaseChannelBuffer(bufPtr); } |