1/* 2 * bz2_opt.c -- 3 * 4 * Implements the C level procedures handling option processing 5 * for ZIP transformations. 6 * 7 * 8 * Copyright (c) 1996 Andreas Kupries (a.kupries@westend.com) 9 * All rights reserved. 10 * 11 * Permission is hereby granted, without written agreement and without 12 * license or royalty fees, to use, copy, modify, and distribute this 13 * software and its documentation for any purpose, provided that the 14 * above copyright notice and the following two paragraphs appear in 15 * all copies of this software. 16 * 17 * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, 18 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS 19 * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE 20 * POSSIBILITY OF SUCH DAMAGE. 21 * 22 * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND 25 * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 26 * ENHANCEMENTS, OR MODIFICATIONS. 27 * 28 * CVS: $Id: bz2_opt.c,v 1.5 2009/05/07 04:57:27 andreas_kupries Exp $ 29 */ 30 31#include "transformInt.h" 32 33/* 34 * forward declarations of all internally used procedures. 35 */ 36 37static Trf_Options CreateOptions _ANSI_ARGS_ ((ClientData clientData)); 38 39static void DeleteOptions _ANSI_ARGS_ ((Trf_Options options, 40 ClientData clientData)); 41 42static int CheckOptions _ANSI_ARGS_ ((Trf_Options options, 43 Tcl_Interp* interp, 44 CONST Trf_BaseOptions* baseOptions, 45 ClientData clientData)); 46 47static int SetOption _ANSI_ARGS_ ((Trf_Options options, 48 Tcl_Interp* interp, 49 CONST char* optname, 50 CONST Tcl_Obj* optvalue, 51 ClientData clientData)); 52 53static int QueryOptions _ANSI_ARGS_ ((Trf_Options options, 54 ClientData clientData)); 55 56 57/* 58 *------------------------------------------------------* 59 * 60 * TrfBZ2Options -- 61 * 62 * ------------------------------------------------* 63 * Accessor to the set of vectors realizing option 64 * processing for ZIP procedures. 65 * ------------------------------------------------* 66 * 67 * Sideeffects: 68 * None. 69 * 70 * Result: 71 * See above. 72 * 73 *------------------------------------------------------* 74 */ 75 76Trf_OptionVectors* 77TrfBZ2Options () 78{ 79 static Trf_OptionVectors optVec = /* THREADING: constant, read-only => safe */ 80 { 81 CreateOptions, 82 DeleteOptions, 83 CheckOptions, 84 NULL, /* no string procedure for 'SetOption' */ 85 SetOption, 86 QueryOptions, 87 NULL /* unseekable, unchanged by options */ 88 }; 89 90 return &optVec; 91} 92 93/* 94 *------------------------------------------------------* 95 * 96 * CreateOptions -- 97 * 98 * ------------------------------------------------* 99 * Create option structure for ZIP transformations. 100 * ------------------------------------------------* 101 * 102 * Sideeffects: 103 * Allocates memory and initializes it as 104 * option structure for ZIP 105 * transformations. 106 * 107 * Result: 108 * A reference to the allocated block of 109 * memory. 110 * 111 *------------------------------------------------------* 112 */ 113 114static Trf_Options 115CreateOptions (clientData) 116ClientData clientData; 117{ 118 TrfZipOptionBlock* o; 119 120 o = (TrfZipOptionBlock*) ckalloc (sizeof (TrfZipOptionBlock)); 121 122 o->mode = TRF_UNKNOWN_MODE; 123 o->level = 9; 124 125 return (Trf_Options) o; 126} 127 128/* 129 *------------------------------------------------------* 130 * 131 * DeleteOptions -- 132 * 133 * ------------------------------------------------* 134 * Delete option structure of a ZIP transformations 135 * ------------------------------------------------* 136 * 137 * Sideeffects: 138 * A memory block allocated by 'CreateOptions' 139 * is released. 140 * 141 * Result: 142 * None. 143 * 144 *------------------------------------------------------* 145 */ 146 147static void 148DeleteOptions (options, clientData) 149Trf_Options options; 150ClientData clientData; 151{ 152 ckfree ((VOID*) options); 153} 154 155/* 156 *------------------------------------------------------* 157 * 158 * CheckOptions -- 159 * 160 * ------------------------------------------------* 161 * Check the given option structure for errors. 162 * ------------------------------------------------* 163 * 164 * Sideeffects: 165 * May modify the given structure to set 166 * default values into uninitialized parts. 167 * 168 * Result: 169 * A standard Tcl error code. 170 * 171 *------------------------------------------------------* 172 */ 173 174static int 175CheckOptions (options, interp, baseOptions, clientData) 176Trf_Options options; 177Tcl_Interp* interp; 178CONST Trf_BaseOptions* baseOptions; 179ClientData clientData; 180{ 181 TrfZipOptionBlock* o = (TrfZipOptionBlock*) options; 182 183 /* 184 * 'bz2' is used, therefore load the required library. 185 * And bail out if it is not available. 186 */ 187 188 if (TCL_OK != TrfLoadBZ2lib (interp)) { 189 return TCL_ERROR; 190 } 191 192 /* 193 * Now perform the real option check. 194 */ 195 196 if (baseOptions->attach == (Tcl_Channel) NULL) /* IMMEDIATE? */ { 197 if (o->mode == TRF_UNKNOWN_MODE) { 198 Tcl_AppendResult (interp, "-mode option not set", (char*) NULL); 199 return TCL_ERROR; 200 } 201 } else /* ATTACH */ { 202 if (o->mode == TRF_UNKNOWN_MODE) { 203 o->mode = TRF_COMPRESS; 204 } 205 } 206 207 return TCL_OK; 208} 209 210/* 211 *------------------------------------------------------* 212 * 213 * SetOption -- 214 * 215 * ------------------------------------------------* 216 * Define value of given option. 217 * ------------------------------------------------* 218 * 219 * Sideeffects: 220 * Sets the given value into the option 221 * structure 222 * 223 * Result: 224 * A standard Tcl error code. 225 * 226 *------------------------------------------------------* 227 */ 228 229static int 230SetOption (options, interp, optname, optvalue, clientData) 231Trf_Options options; 232Tcl_Interp* interp; 233CONST char* optname; 234CONST Tcl_Obj* optvalue; 235ClientData clientData; 236{ 237 /* Possible options: 238 * 239 * -level <number> 240 * -level default 241 * -mode compress|decompress 242 */ 243 244 TrfZipOptionBlock* o = (TrfZipOptionBlock*) options; 245 int len = strlen (optname + 1); 246 CONST char* value; 247 248 switch (optname [1]) { 249 case 'l': 250 if (0 != strncmp (optname, "-level", len)) 251 goto unknown_option; 252 253 value = Tcl_GetStringFromObj ((Tcl_Obj*) optvalue, NULL); 254 len = strlen (value); 255 256 if (0 == strncmp (value, "default", len)) { 257 o->level = 9; 258 } else { 259 int res, val; 260 261 int v; 262 res = Tcl_GetIntFromObj (interp, (Tcl_Obj*) optvalue, &v); 263 val = v; 264 265 if (res != TCL_OK) { 266 return res; 267 } 268 269 if ((val < TRF_MIN_LEVEL) || (val > TRF_MAX_LEVEL)) { 270 Tcl_AppendResult (interp, "level out of range ", (char*) NULL); 271 Tcl_AppendResult (interp, TRF_MIN_LEVEL_STR, (char*) NULL); 272 Tcl_AppendResult (interp, "..", (char*) NULL); 273 Tcl_AppendResult (interp, TRF_MAX_LEVEL_STR, (char*) NULL); 274 return TCL_ERROR; 275 } 276 277 o->level = val; 278 } 279 break; 280 281 case 'm': 282 if (0 != strncmp (optname, "-mode", len)) 283 goto unknown_option; 284 285 value = Tcl_GetStringFromObj ((Tcl_Obj*) optvalue, NULL); 286 len = strlen (value); 287 288 switch (value [0]) { 289 case 'c': 290 if (0 != strncmp (value, "compress", len)) 291 goto unknown_mode; 292 293 o->mode = TRF_COMPRESS; 294 break; 295 296 case 'd': 297 if (0 != strncmp (value, "decompress", len)) 298 goto unknown_mode; 299 300 o->mode = TRF_DECOMPRESS; 301 break; 302 303 default: 304 unknown_mode: 305 Tcl_AppendResult (interp, "unknown mode '", (char*) NULL); 306 Tcl_AppendResult (interp, value, (char*) NULL); 307 Tcl_AppendResult (interp, "', should be 'compress' or 'decompress'", (char*) NULL); 308 return TCL_ERROR; 309 break; 310 } /* switch optvalue */ 311 break; 312 313 default: 314 goto unknown_option; 315 break; 316 } 317 318 return TCL_OK; 319 320 unknown_option: 321 Tcl_AppendResult (interp, "unknown option '", (char*) NULL); 322 Tcl_AppendResult (interp, optname, (char*) NULL); 323 Tcl_AppendResult (interp, "', should be '-level' or '-mode'", (char*) NULL); 324 return TCL_ERROR; 325} 326 327/* 328 *------------------------------------------------------* 329 * 330 * QueryOptions -- 331 * 332 * ------------------------------------------------* 333 * Returns a value indicating wether the encoder or 334 * decoder set of vectors is to be used by immediate 335 * execution. 336 * ------------------------------------------------* 337 * 338 * Sideeffects: 339 * None 340 * 341 * Result: 342 * 1 - use encoder vectors. 343 * 0 - use decoder vectors. 344 * 345 *------------------------------------------------------* 346 */ 347 348static int 349QueryOptions (options, clientData) 350Trf_Options options; 351ClientData clientData; 352{ 353 TrfZipOptionBlock* o = (TrfZipOptionBlock*) options; 354 355 return (o->mode == TRF_COMPRESS ? 1 : 0); 356} 357 358