Tcl Source Code

Check-in [bf9b0551c5]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Differentiate what options may be set by format type.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tip-400-impl
Files: files | file ages | folders
SHA1: bf9b0551c54ba7b98d6cb288e3d01005b0ebd3e1
User & Date: dkf 2012-04-29 07:18:30
Context
2012-04-29
07:23
merge trunk check-in: 8610da4944 user: dkf tags: tip-400-impl
07:18
Differentiate what options may be set by format type. check-in: bf9b0551c5 user: dkf tags: tip-400-impl
2012-04-26
13:52
merge trunk check-in: b440e1e4c3 user: dkf tags: tip-400-impl
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tclZlib.c.

79
80
81
82
83
84
85



86
87
88
89
90
91
92
    Tcl_Channel chan;		/* Reference to the channel itself. */
    Tcl_Channel parent;		/* The underlying source and sink of bytes. */
    int flags;			/* General flag bits, see below... */
    int mode;			/* Either the value TCL_ZLIB_STREAM_DEFLATE
				 * for compression on output, or
				 * TCL_ZLIB_STREAM_INFLATE for decompression
				 * on input. */



    z_stream inStream;		/* Structure used by zlib for decompression of
				 * input. */
    z_stream outStream;		/* Structure used by zlib for compression of
				 * output. */
    char *inBuffer, *outBuffer;	/* Working buffers. */
    int inAllocated, outAllocated;
				/* Sizes of working buffers. */







>
>
>







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
    Tcl_Channel chan;		/* Reference to the channel itself. */
    Tcl_Channel parent;		/* The underlying source and sink of bytes. */
    int flags;			/* General flag bits, see below... */
    int mode;			/* Either the value TCL_ZLIB_STREAM_DEFLATE
				 * for compression on output, or
				 * TCL_ZLIB_STREAM_INFLATE for decompression
				 * on input. */
    int format;			/* What format of data is going on the wire.
				 * Needed so that the correct [fconfigure]
				 * options can be enabled. */
    z_stream inStream;		/* Structure used by zlib for decompression of
				 * input. */
    z_stream outStream;		/* Structure used by zlib for compression of
				 * output. */
    char *inBuffer, *outBuffer;	/* Working buffers. */
    int inAllocated, outAllocated;
				/* Sizes of working buffers. */
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
    Tcl_Obj *levelObj = NULL;
    const OptDescriptor compressionOpts[] = {
	{ "-dictionary", &compDictObj },
	{ "-level", &levelObj },
	{ NULL, NULL }
    };
    const OptDescriptor gzipOpts[] = {
	{ "-dictionary", &compDictObj },
	{ "-header", &gzipHeaderObj },
	{ "-level", &levelObj },
	{ NULL, NULL }
    };
    const OptDescriptor expansionOpts[] = {
	{ "-dictionary", &compDictObj },
	{ NULL, NULL }







<







1984
1985
1986
1987
1988
1989
1990

1991
1992
1993
1994
1995
1996
1997
    Tcl_Obj *levelObj = NULL;
    const OptDescriptor compressionOpts[] = {
	{ "-dictionary", &compDictObj },
	{ "-level", &levelObj },
	{ NULL, NULL }
    };
    const OptDescriptor gzipOpts[] = {

	{ "-header", &gzipHeaderObj },
	{ "-level", &levelObj },
	{ NULL, NULL }
    };
    const OptDescriptor expansionOpts[] = {
	{ "-dictionary", &compDictObj },
	{ NULL, NULL }
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
	break;
    case FMT_GZIP:
	desc = gzipOpts;
	mode = TCL_ZLIB_STREAM_DEFLATE;
	format = TCL_ZLIB_FORMAT_GZIP;
	break;
    case FMT_GUNZIP:
	desc = expansionOpts;
	mode = TCL_ZLIB_STREAM_INFLATE;
	format = TCL_ZLIB_FORMAT_GZIP;
	break;
    default:
	Tcl_AppendResult(interp, "IMPOSSIBLE", NULL);
	return TCL_ERROR;
    }







|







2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
	break;
    case FMT_GZIP:
	desc = gzipOpts;
	mode = TCL_ZLIB_STREAM_DEFLATE;
	format = TCL_ZLIB_FORMAT_GZIP;
	break;
    case FMT_GUNZIP:
	desc = expansionOpts; // FIXME - get header, not set compDict
	mode = TCL_ZLIB_STREAM_INFLATE;
	format = TCL_ZLIB_FORMAT_GZIP;
	break;
    default:
	Tcl_AppendResult(interp, "IMPOSSIBLE", NULL);
	return TCL_ERROR;
    }
2253
2254
2255
2256
2257
2258
2259






2260
2261
2262
2263
2264
2265
2266
	    break;
	case poDictionary:
	    if (++i > objc-1) {
		Tcl_AppendResult(interp,
			"value missing for -dictionary option", NULL);
		Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL);
		return TCL_ERROR;






	    }
	    compDictObj = objv[i];
	    break;
	}
    }

    if (ZlibStackChannelTransform(interp, mode, format, level, chan,







>
>
>
>
>
>







2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
	    break;
	case poDictionary:
	    if (++i > objc-1) {
		Tcl_AppendResult(interp,
			"value missing for -dictionary option", NULL);
		Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL);
		return TCL_ERROR;
	    }
	    if (format == TCL_ZLIB_FORMAT_GZIP) {
		Tcl_AppendResult(interp, "a compression dictionary may not "
			"be set in the gzip format", NULL);
		Tcl_SetErrorCode(interp, "TCL", "ZIP", "BADOPT", NULL);
		return TCL_ERROR;
	    }
	    compDictObj = objv[i];
	    break;
	}
    }

    if (ZlibStackChannelTransform(interp, mode, format, level, chan,
2744
2745
2746
2747
2748
2749
2750

2751
2752
2753

2754
2755
2756
2757
2758
2759
2760
    const char *optionName,
    const char *value)
{
    ZlibChannelData *cd = instanceData;
    Tcl_DriverSetOptionProc *setOptionProc =
	    Tcl_ChannelSetOptionProc(Tcl_GetChannelType(cd->parent));
    static const char *chanOptions = "dictionary flush";

    int haveFlushOpt = (cd->mode == TCL_ZLIB_STREAM_DEFLATE);

    if (optionName && strcmp(optionName, "-dictionary") == 0) {

	Tcl_Obj *compDictObj;

	TclNewStringObj(compDictObj, value, strlen(value));
	Tcl_IncrRefCount(compDictObj);
	(void) Tcl_GetByteArrayFromObj(compDictObj, NULL);
	if (cd->compDictObj) {
	    TclDecrRefCount(cd->compDictObj);







>


|
>







2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
    const char *optionName,
    const char *value)
{
    ZlibChannelData *cd = instanceData;
    Tcl_DriverSetOptionProc *setOptionProc =
	    Tcl_ChannelSetOptionProc(Tcl_GetChannelType(cd->parent));
    static const char *chanOptions = "dictionary flush";
    static const char *gzipChanOptions = "flush";
    int haveFlushOpt = (cd->mode == TCL_ZLIB_STREAM_DEFLATE);

    if (optionName && (strcmp(optionName, "-dictionary") == 0)
	    && (cd->format != TCL_ZLIB_FORMAT_GZIP)) {
	Tcl_Obj *compDictObj;

	TclNewStringObj(compDictObj, value, strlen(value));
	Tcl_IncrRefCount(compDictObj);
	(void) Tcl_GetByteArrayFromObj(compDictObj, NULL);
	if (cd->compDictObj) {
	    TclDecrRefCount(cd->compDictObj);
2805
2806
2807
2808
2809
2810
2811



2812

2813
2814
2815
2816
2817
2818
2819
		return TCL_ERROR;
	    }
	}
	return TCL_OK;
    }

    if (setOptionProc == NULL) {



	return Tcl_BadChannelOption(interp, optionName, chanOptions);

    }

    return setOptionProc(Tcl_GetChannelInstanceData(cd->parent), interp,
	    optionName, value);
}

static int







>
>
>
|
>







2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
		return TCL_ERROR;
	    }
	}
	return TCL_OK;
    }

    if (setOptionProc == NULL) {
	if (cd->format == TCL_ZLIB_FORMAT_GZIP) {
	    return Tcl_BadChannelOption(interp, optionName, gzipChanOptions);
	} else {
	    return Tcl_BadChannelOption(interp, optionName, chanOptions);
	}
    }

    return setOptionProc(Tcl_GetChannelInstanceData(cd->parent), interp,
	    optionName, value);
}

static int
2850
2851
2852
2853
2854
2855
2856

2857
2858
2859
2860
2861
2862
2863
2864
	    Tcl_DStringAppendElement(dsPtr, buf);
	} else {
	    Tcl_DStringAppend(dsPtr, buf, -1);
	    return TCL_OK;
	}
    }


    if (optionName == NULL || strcmp(optionName, "-dictionary") == 0) {
	/*
	 * Embedded NUL bytes are ok; they'll be C080-encoded.
	 */

	if (optionName == NULL) {
	    Tcl_DStringAppendElement(dsPtr, "-dictionary");
	    if (cd->compDictObj) {







>
|







2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
	    Tcl_DStringAppendElement(dsPtr, buf);
	} else {
	    Tcl_DStringAppend(dsPtr, buf, -1);
	    return TCL_OK;
	}
    }

    if ((cd->format != TCL_ZLIB_FORMAT_GZIP) &&
	    (optionName == NULL || strcmp(optionName, "-dictionary") == 0)) {
	/*
	 * Embedded NUL bytes are ok; they'll be C080-encoded.
	 */

	if (optionName == NULL) {
	    Tcl_DStringAppendElement(dsPtr, "-dictionary");
	    if (cd->compDictObj) {
3047
3048
3049
3050
3051
3052
3053

3054
3055
3056
3057
3058
3059
3060

    if (mode != TCL_ZLIB_STREAM_DEFLATE && mode != TCL_ZLIB_STREAM_INFLATE) {
	Tcl_Panic("unknown mode: %d", mode);
    }

    memset(cd, 0, sizeof(ZlibChannelData));
    cd->mode = mode;


    if (format == TCL_ZLIB_FORMAT_GZIP || format == TCL_ZLIB_FORMAT_AUTO) {
	if (mode == TCL_ZLIB_STREAM_DEFLATE) {
	    if (gzipHeaderDictPtr) {
		cd->flags |= OUT_HEADER;
		if (GenerateHeader(interp, gzipHeaderDictPtr, &cd->outHeader,
			NULL) != TCL_OK) {







>







3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076

    if (mode != TCL_ZLIB_STREAM_DEFLATE && mode != TCL_ZLIB_STREAM_INFLATE) {
	Tcl_Panic("unknown mode: %d", mode);
    }

    memset(cd, 0, sizeof(ZlibChannelData));
    cd->mode = mode;
    cd->format = format;

    if (format == TCL_ZLIB_FORMAT_GZIP || format == TCL_ZLIB_FORMAT_AUTO) {
	if (mode == TCL_ZLIB_STREAM_DEFLATE) {
	    if (gzipHeaderDictPtr) {
		cd->flags |= OUT_HEADER;
		if (GenerateHeader(interp, gzipHeaderDictPtr, &cd->outHeader,
			NULL) != TCL_OK) {

Changes to tests/zlib.test.

164
165
166
167
168
169
170




















171
172
173
174
175
176
177
    puts $fd "qwertyuiop"
    fconfigure $fd -flush sync
    puts $fd "qwertyuiop"
} -cleanup {
    catch {close $fd}
    removeFile $file
} -result {}





















test zlib-9.1 "check fcopy with push" -constraints zlib -setup {
    set sfile [makeFile {} testsrc.gz]
    set file [makeFile {} test.gz]
    set f [open $sfile wb]
    puts -nonewline $f [zlib gzip [string repeat a 81920]]
    close $f







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
    puts $fd "qwertyuiop"
    fconfigure $fd -flush sync
    puts $fd "qwertyuiop"
} -cleanup {
    catch {close $fd}
    removeFile $file
} -result {}
test zlib-8.5 {transformation and fconfigure} -setup {
    set file [makeFile {} test.z]
    set fd [open $file wb]
} -constraints zlib -body {
    list [fconfigure $fd] [zlib push compress $fd; fconfigure $fd] \
	[chan pop $fd; fconfigure $fd]
} -cleanup {
    catch {close $fd}
    removeFile $file
} -result {{-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf -checksum 1 -dictionary {}} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf}}
test zlib-8.6 {transformation and fconfigure} -setup {
    set file [makeFile {} test.gz]
    set fd [open $file wb]
} -constraints zlib -body {
    list [fconfigure $fd] [zlib push gzip $fd; fconfigure $fd] \
	[chan pop $fd; fconfigure $fd]
} -cleanup {
    catch {close $fd}
    removeFile $file
} -result {{-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf -checksum 0} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf}}

test zlib-9.1 "check fcopy with push" -constraints zlib -setup {
    set sfile [makeFile {} testsrc.gz]
    set file [makeFile {} test.gz]
    set f [open $sfile wb]
    puts -nonewline $f [zlib gzip [string repeat a 81920]]
    close $f