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 | core-8-5-branch |
Files: | files | file ages | folders |
SHA1: |
47495386202f4a6b059d5cad048cb285 |
User & Date: | dgp 2014-01-30 14:31:17 |
Context
2014-01-30
| ||
14:51 | Eliminate the use of a staging buffer in WriteChars(). check-in: f5f5df0f00 user: dgp tags: trunk | |
14:44 | Fix [22c10c8e79]: core-8-5: msvc6 build: "Side by Side" error check-in: 8a9e78209d user: jan.nijtmans tags: core-8-5-branch | |
14:31 | Eliminate the use of a staging buffer in WriteChars(). check-in: 4749538620 user: dgp tags: core-8-5-branch | |
2014-01-28
| ||
20:23 | The outputStage field is now unused, so never allocate it. check-in: d89e241ea4 user: dgp tags: dgp-optimize-output-stage | |
2014-01-25
| ||
21:41 | sync tcl.m4 with Tk version check-in: fc06c2939f user: jan.nijtmans tags: core-8-5-branch | |
Changes
Changes to generic/tclIO.c.
︙ | ︙ | |||
1485 1486 1487 1488 1489 1490 1491 | statePtr->chPtr = NULL; statePtr->interestMask = 0; statePtr->scriptRecordPtr = NULL; statePtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE; statePtr->timer = NULL; statePtr->csPtrR = NULL; statePtr->csPtrW = NULL; | < < < < < | 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 | 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; |
︙ | ︙ | |||
2753 2754 2755 2756 2757 2758 2759 | if (chanPtr == statePtr->bottomChanPtr) { if (statePtr->channelName != NULL) { ckfree((char *) statePtr->channelName); statePtr->channelName = NULL; } Tcl_FreeEncoding(statePtr->encoding); | < < < < | 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 | if (chanPtr == statePtr->bottomChanPtr) { if (statePtr->channelName != NULL) { ckfree((char *) 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. */ |
︙ | ︙ | |||
3748 3749 3750 3751 3752 3753 3754 | 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 */ | < | < | < | < < < < < < < | | | < < < < | < < < < < < | | < < < < | < < < < < < < | < < < | < < < | < < < | < < < | < < < < | < < | < < < < < < | | | | | < < < | | | | | | | < < | | > > | | | | | | < | > | | | | < > | > | < | > > > > > | > > > > | > > > > > > > > > > > > > > > > | > > | > > < < < > > | < < < < < < > | | > > | > | < | | | | | | | | | | | | | | < < | | < < < | | < < | < > | < | > | | > > > > > | < < < < | < < < | | 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 | 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 ((statePtr->flags & 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) && (statePtr->flags & CHANNEL_UNBUFFERED || (needNlFlush && statePtr->flags & CHANNEL_LINEBUFFERED))) { SetFlag(statePtr, BUFFER_READY); if (FlushChannel(NULL, chanPtr, 0) != 0) { return -1; } } return total; } /* *--------------------------------------------------------------------------- * * TranslateOutputEOL -- |
︙ | ︙ | |||
7189 7190 7191 7192 7193 7194 7195 | sz = 1; } else if (sz > MAX_CHANNEL_BUFFER_SIZE) { sz = MAX_CHANNEL_BUFFER_SIZE; } statePtr = ((Channel *) chan)->state; statePtr->bufSize = sz; | < < < < < < < < < | 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 | sz = 1; } else if (sz > MAX_CHANNEL_BUFFER_SIZE) { sz = MAX_CHANNEL_BUFFER_SIZE; } statePtr = ((Channel *) chan)->state; statePtr->bufSize = sz; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelBufferSize -- * |
︙ | ︙ | |||
7838 7839 7840 7841 7842 7843 7844 | && (statePtr->inQueueHead->nextPtr == NULL) && IsBufferEmpty(statePtr->inQueueHead)) { RecycleBuffer(statePtr, statePtr->inQueueHead, 1); statePtr->inQueueHead = NULL; statePtr->inQueueTail = NULL; } | < < < < < < < < < < < | 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 | && (statePtr->inQueueHead->nextPtr == NULL) && IsBufferEmpty(statePtr->inQueueHead)) { RecycleBuffer(statePtr, statePtr->inQueueHead, 1); statePtr->inQueueHead = NULL; statePtr->inQueueTail = NULL; } return TCL_OK; } /* *---------------------------------------------------------------------- * * CleanupChannelHandlers -- |
︙ | ︙ |