diff options
author | dgp <dgp@users.sourceforge.net> | 2014-11-15 21:46:19 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2014-11-15 21:46:19 (GMT) |
commit | dd3d636ee83cea5c446d72435c1bbf9e843264ec (patch) | |
tree | 856a4e1ab5f053b93224fd940ed188cc4f482e86 /generic | |
parent | f04588b905d72636d0d4a76b907d02a4368592eb (diff) | |
download | tcl-dd3d636ee83cea5c446d72435c1bbf9e843264ec.zip tcl-dd3d636ee83cea5c446d72435c1bbf9e843264ec.tar.gz tcl-dd3d636ee83cea5c446d72435c1bbf9e843264ec.tar.bz2 |
Add to Tcl_ExternalToUtf() a capability to impose a limit on the number
of chars produce in the encoding result. When the flag
TCL_ENCODING_CHAR_LIMIT is set and dstCharsPtr is not NULL, then the
initial value of *dstCharsPtr is taken as the max number of chars to produce.
The limit is imposed in a way that does not require the assistance of the
encoding's driver procs, but the flag is passed on to them in case they
can do better when they know they should. No callers updated yet.
No drivers updated yet.
One difficulty is that this necessarily imposes a pre-translation limit,
and the I/O system has a history of wanting to impose only a post-translation
limit.
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclEncoding.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 0446816..f33e0e6 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -1203,8 +1203,10 @@ Tcl_ExternalToUtf( * output buffer. */ { const Encoding *encodingPtr; - int result, srcRead, dstWrote, dstChars; + int result, srcRead, dstWrote, dstChars = 0; int noTerminate = flags & TCL_ENCODING_NO_TERMINATE; + int charLimited = (flags & TCL_ENCODING_CHAR_LIMIT) && dstCharsPtr; + int maxChars = INT_MAX; Tcl_EncodingState state; if (encoding == NULL) { @@ -1229,6 +1231,9 @@ Tcl_ExternalToUtf( } if (dstCharsPtr == NULL) { dstCharsPtr = &dstChars; + flags &= ~TCL_ENCODING_CHAR_LIMIT; + } else if (charLimited) { + maxChars = *dstCharsPtr; } if (!noTerminate) { @@ -1241,9 +1246,20 @@ Tcl_ExternalToUtf( dstLen--; } - result = encodingPtr->toUtfProc(encodingPtr->clientData, src, srcLen, - flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, - dstCharsPtr); + do { + int savedFlags = flags; + Tcl_EncodingState savedState = *statePtr; + + result = encodingPtr->toUtfProc(encodingPtr->clientData, src, srcLen, + flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, + dstCharsPtr); + if (*dstCharsPtr <= maxChars) { + break; + } + dstLen = Tcl_UtfAtIndex(dst, maxChars) - 1 - dst + TCL_UTF_MAX; + flags = savedFlags; + *statePtr = savedState; + } while (1); if (!noTerminate) { /* ...and then append it */ |