1/* 2 * convert.c -- 3 * 4 * Implements the C level procedures handling option processing 5 * for converter 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: convert.c,v 1.10 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 38CreateOptions _ANSI_ARGS_ ((ClientData clientData)); 39 40static void 41DeleteOptions _ANSI_ARGS_ ((Trf_Options options, 42 ClientData clientData)); 43static int 44CheckOptions _ANSI_ARGS_ ((Trf_Options options, 45 Tcl_Interp* interp, 46 CONST Trf_BaseOptions* baseOptions, 47 ClientData clientData)); 48static int 49SetOption _ANSI_ARGS_ ((Trf_Options options, 50 Tcl_Interp* interp, 51 CONST char* optname, 52 CONST Tcl_Obj* optvalue, 53 ClientData clientData)); 54static int 55QueryOptions _ANSI_ARGS_ ((Trf_Options options, 56 ClientData clientData)); 57 58static void 59SeekQueryOptions _ANSI_ARGS_ ((Tcl_Interp* interp, 60 Trf_Options options, 61 Trf_SeekInformation* seekInfo, 62 ClientData clientData)); 63 64 65/* 66 *------------------------------------------------------* 67 * 68 * Trf_ConverterOptions -- 69 * 70 * ------------------------------------------------* 71 * Accessor to the set of vectors realizing option 72 * processing for converter procedures. 73 * ------------------------------------------------* 74 * 75 * Sideeffects: 76 * None. 77 * 78 * Result: 79 * See above. 80 * 81 *------------------------------------------------------* 82 */ 83 84Trf_OptionVectors* 85Trf_ConverterOptions () 86{ 87 static Trf_OptionVectors optVec = /* THREADING: constant, read-only => safe */ 88 { 89 CreateOptions, 90 DeleteOptions, 91 CheckOptions, 92 NULL, /* no string procedure for 'SetOption' */ 93 SetOption, 94 QueryOptions, 95 SeekQueryOptions 96 }; 97 98 return &optVec; 99} 100 101/* 102 *------------------------------------------------------* 103 * 104 * CreateOptions -- 105 * 106 * ------------------------------------------------* 107 * Create option structure for converter transformations. 108 * ------------------------------------------------* 109 * 110 * Sideeffects: 111 * Allocates memory and initializes it as 112 * option structure for converter 113 * transformations. 114 * 115 * Result: 116 * A reference to the allocated block of 117 * memory. 118 * 119 *------------------------------------------------------* 120 */ 121 122static Trf_Options 123CreateOptions (clientData) 124ClientData clientData; 125{ 126 Trf_ConverterOptionBlock* o; 127 128 o = (Trf_ConverterOptionBlock*) ckalloc (sizeof (Trf_ConverterOptionBlock)); 129 o->mode = TRF_UNKNOWN_MODE; 130 131 return (Trf_Options) o; 132} 133 134/* 135 *------------------------------------------------------* 136 * 137 * DeleteOptions -- 138 * 139 * ------------------------------------------------* 140 * Delete option structure of a converter transformations 141 * ------------------------------------------------* 142 * 143 * Sideeffects: 144 * A memory block allocated by 'CreateOptions' 145 * is released. 146 * 147 * Result: 148 * None. 149 * 150 *------------------------------------------------------* 151 */ 152 153static void 154DeleteOptions (options, clientData) 155Trf_Options options; 156ClientData clientData; 157{ 158 Trf_ConverterOptionBlock* o = (Trf_ConverterOptionBlock*) options; 159 ckfree ((VOID*) o); 160} 161 162/* 163 *------------------------------------------------------* 164 * 165 * CheckOptions -- 166 * 167 * ------------------------------------------------* 168 * Check the given option structure for errors. 169 * ------------------------------------------------* 170 * 171 * Sideeffects: 172 * May modify the given structure to set 173 * default values into uninitialized parts. 174 * 175 * Result: 176 * A standard Tcl error code. 177 * 178 *------------------------------------------------------* 179 */ 180 181static int 182CheckOptions (options, interp, baseOptions, clientData) 183Trf_Options options; 184Tcl_Interp* interp; 185CONST Trf_BaseOptions* baseOptions; 186ClientData clientData; 187{ 188 Trf_ConverterOptionBlock* o = (Trf_ConverterOptionBlock*) options; 189 190 if (baseOptions->attach == (Tcl_Channel) NULL) /* IMMEDIATE? */ { 191 if (o->mode == TRF_UNKNOWN_MODE) { 192 Tcl_AppendResult (interp, "-mode option not set", (char*) NULL); 193 return TCL_ERROR; 194 } 195 } else /* ATTACH */ { 196 if (o->mode == TRF_UNKNOWN_MODE) { 197 o->mode = TRF_ENCODE_MODE; 198 } 199 } 200 201 return TCL_OK; 202} 203 204/* 205 *------------------------------------------------------* 206 * 207 * SetOption -- 208 * 209 * ------------------------------------------------* 210 * Define value of given option. 211 * ------------------------------------------------* 212 * 213 * Sideeffects: 214 * Sets the given value into the option 215 * structure 216 * 217 * Result: 218 * A standard Tcl error code. 219 * 220 *------------------------------------------------------* 221 */ 222 223static int 224SetOption (options, interp, optname, optvalue, clientData) 225Trf_Options options; 226Tcl_Interp* interp; 227CONST char* optname; 228CONST Tcl_Obj* optvalue; 229ClientData clientData; 230{ 231 Trf_ConverterOptionBlock* o = (Trf_ConverterOptionBlock*) options; 232 int len; 233 CONST char* value; 234 235 len = strlen (optname+1); 236 237 switch (optname [1]) { 238 case 'm': 239 if (0 != strncmp (optname, "-mode", len)) 240 goto unknown_option; 241 242 value = Tcl_GetStringFromObj ((Tcl_Obj*) optvalue, NULL); 243 len = strlen (value); 244 245 switch (value [0]) { 246 case 'e': 247 if (0 != strncmp (value, "encode", len)) 248 goto unknown_mode; 249 250 o->mode = TRF_ENCODE_MODE; 251 break; 252 253 case 'd': 254 if (0 != strncmp (value, "decode", len)) 255 goto unknown_mode; 256 257 o->mode = TRF_DECODE_MODE; 258 break; 259 260 default: 261 unknown_mode: 262 Tcl_AppendResult (interp, "unknown mode '", (char*) NULL); 263 Tcl_AppendResult (interp, value, (char*) NULL); 264 Tcl_AppendResult (interp, "', should be 'encode' or 'decode'", (char*) NULL); 265 return TCL_ERROR; 266 break; 267 } /* switch optvalue */ 268 break; 269 270 default: 271 goto unknown_option; 272 break; 273 } 274 275 return TCL_OK; 276 277 unknown_option: 278 Tcl_AppendResult (interp, "unknown option '", (char*) NULL); 279 Tcl_AppendResult (interp, optname, (char*) NULL); 280 Tcl_AppendResult (interp, "', should be '-mode'", (char*) NULL); 281 return TCL_ERROR; 282} 283 284/* 285 *------------------------------------------------------* 286 * 287 * QueryOptions -- 288 * 289 * ------------------------------------------------* 290 * Returns a value indicating wether the encoder or 291 * decoder set of vectors is to be used by immediate 292 * execution. 293 * ------------------------------------------------* 294 * 295 * Sideeffects: 296 * None 297 * 298 * Result: 299 * 1 - use encoder vectors. 300 * 0 - use decoder vectors. 301 * 302 *------------------------------------------------------* 303 */ 304 305static int 306QueryOptions (options, clientData) 307Trf_Options options; 308ClientData clientData; 309{ 310 Trf_ConverterOptionBlock* o = (Trf_ConverterOptionBlock*) options; 311 312 return (o->mode == TRF_ENCODE_MODE ? 1 : 0); 313} 314 315/* 316 *------------------------------------------------------* 317 * 318 * SeekQueryOptions -- 319 * 320 * ------------------------------------------------* 321 * Modifies the natural seek policy according to the 322 * configuration of the transformation. 323 * ------------------------------------------------* 324 * 325 * Sideeffects: 326 * May modify 'seekInfo'. 327 * 328 * Result: 329 * None. 330 * 331 *------------------------------------------------------* 332 */ 333 334static void 335SeekQueryOptions (interp, options, seekInfo, clientData) 336 Tcl_Interp* interp; 337 Trf_Options options; 338 Trf_SeekInformation* seekInfo; 339 ClientData clientData; 340{ 341 Trf_ConverterOptionBlock* o = (Trf_ConverterOptionBlock*) options; 342 343 if (o->mode == TRF_DECODE_MODE) { 344 /* The conversion is backward, swap the seek information. 345 */ 346 347 int t = seekInfo->numBytesTransform; 348 seekInfo->numBytesTransform = seekInfo->numBytesDown; 349 seekInfo->numBytesDown = t; 350 } 351} 352