1 /*
2 This product contains certain software code or other information
3 ("AT&T Software") proprietary to AT&T Corp. ("AT&T").  The AT&T
4 Software is provided to you "AS IS".  YOU ASSUME TOTAL RESPONSIBILITY
5 AND RISK FOR USE OF THE AT&T SOFTWARE.  AT&T DOES NOT MAKE, AND
6 EXPRESSLY DISCLAIMS, ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND
7 WHATSOEVER, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
8 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, WARRANTIES OF
9 TITLE OR NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS, ANY
10 WARRANTIES ARISING BY USAGE OF TRADE, COURSE OF DEALING OR COURSE OF
11 PERFORMANCE, OR ANY WARRANTY THAT THE AT&T SOFTWARE IS "ERROR FREE" OR
12 WILL MEET YOUR REQUIREMENTS.
13 
14 Unless you accept a license to use the AT&T Software, you shall not
15 reverse compile, disassemble or otherwise reverse engineer this
16 product to ascertain the source code for any AT&T Software.
17 
18 (c) AT&T Corp. All rights reserved.  AT&T is a registered trademark of AT&T Corp.
19 
20 ***********************************************************************
21 
22 History:
23 
24       27/12/2002 Hedzer Westra <hhwestra@cs.uu.nl>
25 */
26 
27 //********************************************************************
28 //********************************************************************
29 
30 /* This module contains the base X compressors:
31 		binary	b
32 		hex		x
33 		hexcase	X	maintains case
34 		base64	base64
35 
36 		extensions to other bases should be straightforward,
37 		although those will not be as efficient as possible
38 		(as is hexcase!) since the numbers will be parsed into
39 		unsigned int32 numbers. The total number can
40 		have an arbitrary number of digits. Negative numbers are
41 		not supported. A 0x or 0X prefix for hex(case) strings is
42 		maintained, zeros at the start as well.
43  */
44 
45 #include "stdafx.h"
46 #include <math.h>
47 
48 /* constructor */
BaseXNumCompressor(Session * s,unsigned long mymindigits,unsigned char b,unsigned char ishex)49 BaseXNumCompressor::BaseXNumCompressor(
50 		Session *s,
51 		unsigned long mymindigits,
52 		unsigned char b,
53 		unsigned char ishex
54 	  ): UserCompressor(s)
55 {
56 	Init(mymindigits, b, ishex);
57 }
58 
Init(unsigned long mymindigits,unsigned char b,unsigned char ishex)59 void BaseXNumCompressor::Init(
60 			 unsigned long mymindigits,
61   			 unsigned char b,
62 			 unsigned char ishex)
63 {
64    mindigits=mymindigits;
65    datasize=0;
66 	contnum=1;
67 	isrejecting=1;
68 	canoverlap=1;
69 	isfixedlen=0;
70    base = b;
71    preflag = 0;
72 	ishexcase = ishex;
73 	preskip = 0;
74 	if (base == 64) {
75 		/* we use only 24 bits (3 Bytes) */
76 		maxdigits = 4;
77 	} else {
78 		/* a hack to get 1<<32 without overflow.. */
79 		maxdigits = log(65536.0*65536.0) / log(base);
80 	}
81 }
82 
83 /* helpers */
char2num(unsigned char c)84 long BaseXNumCompressor::char2num(unsigned char c)
85 {
86 	long n;
87 
88 	/* Note: base 63 and 65-255 are not supported */
89 	if (c < '0') {
90 		n = -1;
91 	} else if ((n = c - '0') > 10-1) {
92 		/* not numeric (0-9) */
93 		if (!ishexcase) {
94 			/* convert to upper case if not case sensitive */
95 			c = toupper(c);
96 		}
97 		if((n = c - 'A' + 10) > 10+26-1) {
98 			/* not upper case (10-35) */
99 			if((n = c - 'a' + 10 + 26) > 10+26+26-1) {
100 				/* not lower case (36-61) */
101 				n = -1;
102 			} else if (ishexcase && c < 'g') {
103 				/* hexcase is implemented using base-22 */
104 				n -= 'Z'-'G'+1;
105 			}
106 		}
107 	}
108 
109 	/* check if within base limits */
110 	if (n >= base) {
111 		/* illegal char */
112 		n = -1;
113 	}
114 
115 	return n;
116 }
117 
char2num(unsigned char c)118 long Base64Compressor::char2num(unsigned char c)
119 {
120 	long n;
121 
122 	if (c < '0') {
123 		/* char should be skipped */
124 		n = 65;
125 	}
126 	if((n = c - 'A') > 26-1 || n < 0) {
127 		/* not upper case (0-25) */
128 		if((n = c - 'a' + 26) > 26+26-1 || n < 26) {
129 			/* not lower case (26-51) */
130 			if((n = c - '0' + 26 + 26) > 10+26+26-1 || n < 26+26) {
131 				/* not numeric (52-61) */
132 				switch (c) {
133 					case '+':
134 						n = 62;
135 						break;
136 					case '/':
137 						n = 63;
138 						break;
139 					case '=':
140 						/* padding */
141 						n = 64;
142 						break;
143 					default:
144 						/* char should be skipped */
145 						n = 65;
146 						break;
147 				}
148 			}
149 		}
150 	}
151 	return n;
152 }
153 
154 /* checker / compressor */
ParseString(char * str,unsigned len,char * dataptr)155 char BaseXNumCompressor::ParseString(char *str,unsigned len,char *dataptr)
156 {
157 	unsigned int i = 0, j = 0;
158 	unsigned int num = 0;
159 
160 	/* init flags & counters */
161 	preflag = 0;
162 	preskip = 0;
163 	numdigits = 0;
164 
165 	/* check  for prefixes */
166 	if ((base == 16 || base == 22) && len>=XMILL_HEX_PREFIX_LEN) {
167 		if (!strncmp(str, XMILL_HEX_0x_STR, XMILL_HEX_PREFIX_LEN)) {
168 			preflag |= XMILL_HEX_0x;
169 			preskip = XMILL_HEX_PREFIX_LEN;
170 		} else if (!strncmp(str, XMILL_HEX_0X_STR, XMILL_HEX_PREFIX_LEN)) {
171 			preflag |= XMILL_HEX_0X;
172 			preskip = XMILL_HEX_PREFIX_LEN;
173 		}
174 	}
175 	/* check all digits and calculate compressed length */
176 	for (i=preskip; i<len; i++) {
177 		if ((num = char2num((unsigned char)str[i])) == -1)
178 			return FALSE;
179 		if (num < base && ++j == maxdigits) {
180 			j = 0;
181 			numdigits++;
182 		}
183 	}
184 	preflag |= j << XMILL_HEX_NUM_BITS;
185 
186 	return TRUE;
187 }
188 
CompressString(char * str,unsigned len,CompressContainer * cont,char * dataptr)189 void BaseXNumCompressor::CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr)
190 {
191 	unsigned long value = 0;
192 	unsigned int i = preskip, j = 0;
193 
194 	/* store header */
195 	cont->StoreChar(preflag);
196 	cont->StoreUInt32(numdigits);
197 
198 	/* store number */
199 	while (i<len) {
200 		value *= base;
201 		value += (unsigned long)char2num((unsigned char)str[i++]);
202 		if (++j == maxdigits) {
203 			/* flush */
204 		   cont->StoreUInt32(value);
205 			j = 0;
206 			value = 0;
207 		}
208 	}
209 	/* store trailing number */
210 	if (j > 0) {
211 		cont->StoreUInt32(value);
212 	}
213 
214 #if 0
215 	/* store footer */
216 	postflag |= j;
217 	cont->StoreChar(postflag);
218 #endif
219 }
220 
221 /* constructors */
BaseXNumUncompressor()222 BaseXNumUncompressor::BaseXNumUncompressor(): UserUncompressor()
223 {
224 }
225 
BaseXNumUncompressor(unsigned char b,unsigned char ishex,unsigned long mymindigits)226 BaseXNumUncompressor::BaseXNumUncompressor(
227 	 unsigned char b,
228 	 unsigned char ishex,
229 	 unsigned long mymindigits
230    ): UserUncompressor()
231 {
232 	Init(b, ishex, mymindigits);
233 }
234 
BaseXNumUncompressor(Session * s,unsigned char b,unsigned char ishex,unsigned long mymindigits)235 BaseXNumUncompressor::BaseXNumUncompressor(
236 	 Session *s,
237  	 unsigned char b,
238  	 unsigned char ishex,
239 	 unsigned long mymindigits
240 	): UserUncompressor(s)
241 {
242 	Init(b, ishex, mymindigits);
243 }
244 
Init(unsigned char b,unsigned char ishex,unsigned long mymindigits)245 void BaseXNumUncompressor::Init(
246 		unsigned char b,
247 		unsigned char ishex,
248 		unsigned long mymindigits)
249 {
250 	mindigits=mymindigits;
251    datasize=0;
252 	contnum=1;
253    base = b;
254    preflag = 0;
255 	ishexcase = ishex;
256 	if (base == 64) {
257 		/* we use only 24 bits (3 Bytes) */
258 		maxdigits = 4;
259 	} else {
260 		/* a hack to get 1<<32 without overflow.. */
261 		maxdigits = log(65536.0*65536.0) / log(base);
262 		startdiv = 1;
263 		for (int i=1; i<maxdigits; i++)
264 			startdiv *= base;
265 	}
266 }
267 
num2char(unsigned int n)268 unsigned char BaseXNumUncompressor::num2char(unsigned int n)
269 {
270 	if (n < 10) {
271 		return '0' + n;
272 	} else if (ishexcase && n>15) {
273 		return 'a' + n - 16;
274 	} else if (n < 26) {
275 		return 'A' + n - 10;
276 	} else if (n < 62) {
277 		return 'a' + n - 10 - 26;
278 	} else {
279 		return '?';
280 	}
281 }
282 
283 /* uncompressor */
UncompressItem(UncompressContainer * cont,char * dataptr,XMLOutput * xoutput)284 void BaseXNumUncompressor::UncompressItem(UncompressContainer *cont,char *dataptr,XMLOutput *xoutput)
285 {
286 	/* load header */
287 	preflag = (unsigned char)cont->LoadChar();
288 	numdigits = cont->LoadUInt32();
289 	restdigits = (preflag >> XMILL_HEX_NUM_BITS) & XMILL_BASEX_MAXDIGITS-1;
290 
291 	/* prefix */
292 	if  ( (base == 16 || base == 22)
293 		 && preflag & XMILL_HEX_BITS) {
294 		if ((preflag & XMILL_HEX_BITS) == XMILL_HEX_0X) {
295 			xoutput->characters(XMILL_HEX_0X_STR, XMILL_HEX_PREFIX_LEN);
296 		} else if ((preflag & XMILL_HEX_BITS) == XMILL_HEX_0x) {
297 			xoutput->characters(XMILL_HEX_0x_STR, XMILL_HEX_PREFIX_LEN);
298 		}
299 	}
300 
301    /* prefix with zeros */
302 	unsigned int realdigits = numdigits * maxdigits + restdigits;
303 	if (mindigits > 0) {
304 		unsigned int extradigits = mindigits - realdigits;
305 		while (extradigits > 0) {
306 			realdigits = min(extradigits, sizeof(XMILL_ZEROS_STR)-1);
307 			xoutput->characters(XMILL_ZEROS_STR, realdigits);
308 			extradigits -= realdigits;
309 		}
310 	}
311 
312 	/* print number */
313 	if (numdigits > 0 || restdigits > 0) {
314 		decodeNum (cont, xoutput);
315 	}
316 }
317 
decodeNum(UncompressContainer * cont,XMLOutput * xoutput)318 void BaseXNumUncompressor::decodeNum(UncompressContainer *cont, XMLOutput *xoutput)
319 {
320 	unsigned long value = 0;
321 	unsigned int len = 0;
322 	unsigned int div = 0;
323 	unsigned int curmaxdigits = maxdigits;
324 
325 	while (numdigits > 0 || restdigits > 0) {
326 		/* load encoded number */
327 		value = cont->LoadUInt32();
328 		/* init counters etc */
329 		len = 0;
330 		if (numdigits == 0) {
331 			curmaxdigits = restdigits;
332 			restdigits = 0;
333 			div = 1;
334 			for (unsigned int i=1; i<curmaxdigits; i++)
335 				div *= base;
336 		} else {
337 			div = startdiv;
338 			numdigits--;
339 		}
340 		while (len < curmaxdigits) {
341 			/* decode number to a string */
342 			buffer[len++] = num2char(value / div);
343 			value %= div;
344 			div /= base;
345 		}
346 
347 		/* output number */
348 		xoutput->characters((char*)buffer, len);
349 
350 #if 0
351 		postflag = (unsigned char)cont->LoadChar();
352 #endif
353 	}
354 }
355 
356 /* constructors for subclasses */
357 /* bin */
BinCompressor(Session * s,unsigned long mymindigits)358 BinCompressor::BinCompressor(Session *s, unsigned long mymindigits):
359 	BaseXNumCompressor(s, mymindigits, 2, FALSE)
360 {}
361 
BinUncompressor(unsigned long mymindigits)362 BinUncompressor::BinUncompressor(unsigned long mymindigits):
363 	BaseXNumUncompressor(2, FALSE, mymindigits)
364 {}
365 
BinUncompressor(Session * s,unsigned long mymindigits)366 BinUncompressor::BinUncompressor(Session *s, unsigned long mymindigits):
367 	BaseXNumUncompressor(s, 2, FALSE, mymindigits)
368 {}
369 
370 /* hex */
HexCompressor(Session * s,unsigned long mymindigits)371 HexCompressor::HexCompressor(Session *s, unsigned long mymindigits):
372 	BaseXNumCompressor(s, mymindigits, 16, FALSE)
373 {}
374 
HexUncompressor(unsigned long mymindigits)375 HexUncompressor::HexUncompressor(unsigned long mymindigits):
376 	BaseXNumUncompressor(16, FALSE, mymindigits)
377 {}
378 
HexUncompressor(Session * s,unsigned long mymindigits)379 HexUncompressor::HexUncompressor(Session *s, unsigned long mymindigits):
380 	BaseXNumUncompressor(s, 16, FALSE, mymindigits)
381 {}
382 
383 /* hexcase */
HexCaseCompressor(Session * s,unsigned long mymindigits)384 HexCaseCompressor::HexCaseCompressor(Session *s, unsigned long mymindigits):
385 	BaseXNumCompressor(s, mymindigits, 22, TRUE)
386 {}
387 
HexCaseUncompressor(unsigned long mymindigits)388 HexCaseUncompressor::HexCaseUncompressor(unsigned long mymindigits):
389 	BaseXNumUncompressor(22, TRUE, mymindigits)
390 {}
391 
HexCaseUncompressor(Session * s,unsigned long mymindigits)392 HexCaseUncompressor::HexCaseUncompressor(Session *s, unsigned long mymindigits):
393 	BaseXNumUncompressor(s, 22, TRUE, mymindigits)
394 {}
395 
396 /* base64 */
Base64Compressor(Session * s,unsigned long mymindigits)397 Base64Compressor::Base64Compressor(Session *s, unsigned long mymindigits):
398 	BaseXNumCompressor(s, mymindigits, 64, FALSE)
399 {}
400 
Base64Uncompressor(unsigned long mymindigits)401 Base64Uncompressor::Base64Uncompressor(unsigned long mymindigits):
402 	BaseXNumUncompressor(64, FALSE, mymindigits)
403 {}
404 
Base64Uncompressor(Session * s,unsigned long mymindigits)405 Base64Uncompressor::Base64Uncompressor(Session *s, unsigned long mymindigits):
406 	BaseXNumUncompressor(s, 64, FALSE, mymindigits)
407 {}
408 
409 /* base64 implementation */
CompressString(char * str,unsigned len,CompressContainer * cont,char * dataptr)410 void Base64Compressor::CompressString(char *str,unsigned len,CompressContainer *cont,char *dataptr)
411 {
412 	unsigned long value = 0, val = 0;
413 	unsigned int i = preskip, j = 0;
414 
415 	/* store header */
416 	cont->StoreChar(preflag);
417 	cont->StoreUInt32(numdigits);
418 
419 	/* store base64 string */
420 	while (i<len) {
421 		if (((val = (unsigned long)char2num((unsigned char)str[i++])) != -1)
422 			 && val < 64) {
423 			/* we skip invalid or padding chars, which should be done according to RFC 2045 */
424 			value <<= 6;
425 			value |= val;
426 			if (++j == 4) {
427 				/* flush 3 Bytes per 4 input Bytes (4*6 bits == 3*8 bits) */
428 				cont->StoreChar((unsigned char)(value>>16)&255);
429 				cont->StoreChar((unsigned char)(value>>8)&255);
430 				cont->StoreChar((unsigned char)value&255);
431 				j = 0;
432 				value = 0;
433 			}
434 		}
435 	}
436 
437 	/* store extra chars */
438 	value <<= 6 * (4-j);
439 	if (j >= 1)
440 		cont->StoreChar((unsigned char)(value>>16)&255);
441 	if (j >= 2)
442 		cont->StoreChar((unsigned char)(value>>8)&255);
443 	if (j == 3)
444 		cont->StoreChar((unsigned char)value&255);
445 
446 #if 0
447 	/* store footer */
448 	postflag |= j;
449 	cont->StoreChar(postflag);
450 #endif
451 }
452 
num2char(unsigned int c)453 unsigned char Base64Uncompressor::num2char(unsigned int c)
454 {
455 	if (c < 26) {
456 		return c + 'A';
457 	} else if (c < 52) {
458 		return c - 26 + 'a';
459 	} else if (c < 62) {
460 		return c - 52 + '0';
461 	} else if (c == 62) {
462 		return '+';
463 	} else if (c == 63) {
464 		return '/';
465 	} else {
466 		return '=';
467 	}
468 }
469 
decodeNum(UncompressContainer * cont,XMLOutput * xoutput)470 void Base64Uncompressor::decodeNum(UncompressContainer *cont, XMLOutput *xoutput)
471 {
472 	unsigned long value = 0;
473 
474 	while (numdigits > 0 || restdigits > 0) {
475 		/* load 3 encoded Bytes */
476 		if (numdigits == 0) {
477 			value  = (((unsigned long)cont->LoadChar()) & 255) << 16;
478 			if (restdigits > 1)
479 				value |= (((unsigned long)cont->LoadChar()) & 255) << 8;
480 			if (restdigits > 2)
481 				value |= (unsigned long)cont->LoadChar() & 255;
482 		} else {
483 			value  = (((unsigned long)cont->LoadChar()) & 255) << 16;
484 			value |= (((unsigned long)cont->LoadChar()) & 255) << 8;
485 			value |= (unsigned long)cont->LoadChar() & 255;
486 		}
487 
488 		buffer[0] = num2char((value >> 18) & 63);	// bits 23-18
489 		buffer[1] = num2char((value >> 12) & 63); // bits 17-12
490 		buffer[2] = num2char((value >> 6) & 63);	// bits 11-6
491 		buffer[3] = num2char(value & 63);			// bits 5-0
492 
493 		/* is padding at the end needed ? */
494 		if (numdigits == 0) {
495 			for (unsigned int i=3; i>=restdigits; i--)
496 				buffer[i] = '=';
497 			restdigits = 0;
498 		} else {
499 			numdigits--;
500 		}
501 
502 		/* output 4 base64 Bytes */
503 		xoutput->characters((char*)buffer, 4);
504 
505 #if 0
506 		postflag = (unsigned char)cont->LoadChar();
507 #endif
508 	}
509 }
510 
511 /* factories */
512 /* base-x */
GetName()513 char *BaseXNumCompressorFactory::GetName()
514 {
515 	return "basex";
516 }
GetDescription()517 char *BaseXNumCompressorFactory::GetDescription()
518 {
519 	return "Compressor for arbitrary-length arbitrary-base numbers";
520 }
521 
InstantiateCompressor(char * paramstr,int len)522 UserCompressor *BaseXNumCompressorFactory::InstantiateCompressor(char *paramstr,int len)
523 {
524    unsigned long mindigits = 0;
525 	unsigned char base = 10;
526 	char *str = NULL;
527 
528    if (paramstr) {
529 		/* NULL-terminate parameter string */
530       char savechar = paramstr[len];
531       paramstr[len]= '\0';
532 		/* check for second argument */
533 		str = strstr(paramstr, " ");
534 		/* parse first (==base) */
535       base = atoi(paramstr);
536 		/* parse second (==mindigits) */
537 		if (str && str[0]) {
538 	      mindigits = atoi(str+1);
539 		}
540 		/* fix paramstr */
541       paramstr[len] = savechar;
542 		/* check base */
543       if(base <= 0) {
544          XMillException *e = new XMillException(XMILL_ERR_ARGUMENTS, "Invalid parameter '");
545          e->ErrorCont(paramstr,len);
546          e->ErrorCont("' for compressor 'basex'!");
547          throw e;
548       }
549    }
550    return new BaseXNumCompressor(session, mindigits, base, false);
551 }
552 
InstantiateUncompressor(char * paramstr,int len)553 UserUncompressor *BaseXNumCompressorFactory::InstantiateUncompressor(char *paramstr,int len)
554 {
555    unsigned long mindigits=0;
556 	unsigned char base = 10;
557 	char *str = NULL;
558 
559 	if (paramstr) {
560 		/* NULL-terminate parameter string */
561       char savechar = paramstr[len];
562       paramstr[len]= '\0';
563 		/* check for second argument */
564 		str = strstr(paramstr, " ");
565 		/* parse first (==base) */
566       base = atoi(paramstr);
567 		/* parse second (==mindigits) */
568 		if (str && str[0]) {
569 	      mindigits = atoi(str+1);
570 		}
571 		/* fix paramstr */
572       paramstr[len] = savechar;
573       return new BaseXNumUncompressor(session, base, FALSE, mindigits);
574 	} else {
575       return &uncompressor;
576 	}
577 }
578 
579 /* hex */
GetName()580 char *HexCompressorFactory::GetName()
581 {
582 	return "x";
583 }
GetDescription()584 char *HexCompressorFactory::GetDescription()
585 {
586 	return "Compressor for large hex numbers";
587 }
588 
InstantiateCompressor(char * paramstr,int len)589 UserCompressor *HexCompressorFactory::InstantiateCompressor(char *paramstr,int len)
590 {
591    unsigned long mindigits=0;
592    if(paramstr!=NULL)
593    {
594       char savechar=paramstr[len];
595       paramstr[len]=0;
596       mindigits=atoi(paramstr);
597       paramstr[len]=savechar;
598       if(mindigits<=0)
599       {
600          XMillException *e = new XMillException(XMILL_ERR_ARGUMENTS, "Invalid parameter '");
601          e->ErrorCont(paramstr,len);
602          e->ErrorCont("' for compressor 'x'!");
603          throw e;
604       }
605    }
606    return new HexCompressor(session, mindigits);
607 }
608 
InstantiateUncompressor(char * paramstr,int len)609 UserUncompressor *HexCompressorFactory::InstantiateUncompressor(char *paramstr,int len)
610 {
611    unsigned long mindigits=0;
612    if(paramstr!=NULL)
613    {
614       char savechar=paramstr[len];
615       paramstr[len]=0;
616       mindigits=atoi(paramstr);
617       paramstr[len]=savechar;
618       return new HexUncompressor(session, mindigits);
619    }
620    else
621       return &uncompressor;
622 }
623 
624 /* hex-case */
GetName()625 char *HexCaseCompressorFactory::GetName()
626 {
627 	return "X";
628 }
GetDescription()629 char *HexCaseCompressorFactory::GetDescription()
630 {
631 	return "Compressor for case sensitive large hex numbers";
632 }
633 
InstantiateCompressor(char * paramstr,int len)634 UserCompressor *HexCaseCompressorFactory::InstantiateCompressor(char *paramstr,int len)
635 {
636    unsigned long mindigits=0;
637    if(paramstr!=NULL)
638    {
639       char savechar=paramstr[len];
640       paramstr[len]=0;
641       mindigits=atoi(paramstr);
642       paramstr[len]=savechar;
643       if(mindigits<=0)
644       {
645          XMillException *e = new XMillException(XMILL_ERR_ARGUMENTS, "Invalid parameter '");
646          e->ErrorCont(paramstr,len);
647          e->ErrorCont("' for compressor 'X'!");
648          throw e;
649       }
650    }
651    return new HexCaseCompressor(session, mindigits);
652 }
653 
InstantiateUncompressor(char * paramstr,int len)654 UserUncompressor *HexCaseCompressorFactory::InstantiateUncompressor(char *paramstr,int len)
655 {
656    unsigned long mindigits=0;
657    if(paramstr!=NULL)
658    {
659       char savechar=paramstr[len];
660       paramstr[len]=0;
661       mindigits=atoi(paramstr);
662       paramstr[len]=savechar;
663       return new HexCaseUncompressor(session, mindigits);
664    }
665    else
666       return &uncompressor;
667 }
668 
669 /* binary */
GetName()670 char *BinCompressorFactory::GetName()
671 {
672 	return "b";
673 }
GetDescription()674 char *BinCompressorFactory::GetDescription()
675 {
676 	return "Compressor for large binary numbers";
677 }
678 
InstantiateCompressor(char * paramstr,int len)679 UserCompressor *BinCompressorFactory::InstantiateCompressor(char *paramstr,int len)
680 {
681    unsigned long mindigits=0;
682    if(paramstr!=NULL)
683    {
684       char savechar=paramstr[len];
685       paramstr[len]=0;
686       mindigits=atoi(paramstr);
687       paramstr[len]=savechar;
688       if(mindigits<=0)
689       {
690          XMillException *e = new XMillException(XMILL_ERR_ARGUMENTS, "Invalid parameter '");
691          e->ErrorCont(paramstr,len);
692          e->ErrorCont("' for compressor 'b'!");
693          throw e;
694       }
695    }
696    return new BinCompressor(session, mindigits);
697 }
698 
InstantiateUncompressor(char * paramstr,int len)699 UserUncompressor *BinCompressorFactory::InstantiateUncompressor(char *paramstr,int len)
700 {
701    unsigned long mindigits=0;
702    if(paramstr!=NULL)
703    {
704       char savechar=paramstr[len];
705       paramstr[len]=0;
706       mindigits=atoi(paramstr);
707       paramstr[len]=savechar;
708       return new BinUncompressor(session, mindigits);
709    }
710    else
711       return &uncompressor;
712 }
713 
714 /* base64 */
GetName()715 char *Base64CompressorFactory::GetName()
716 {
717 	return "base64";
718 }
GetDescription()719 char *Base64CompressorFactory::GetDescription()
720 {
721 	return "Compressor for base64 encoded strings";
722 }
723 
InstantiateCompressor(char * paramstr,int len)724 UserCompressor *Base64CompressorFactory::InstantiateCompressor(char *paramstr,int len)
725 {
726    unsigned long mindigits=0;
727    if(paramstr!=NULL)
728    {
729       throw new XMillException(XMILL_ERR_ARGUMENTS,
730 			"base64 does not accept any parameters!");
731 /*      char savechar=paramstr[len];
732       paramstr[len]=0;
733       mindigits=atoi(paramstr);
734       paramstr[len]=savechar;
735       if(mindigits<=0)
736       {
737          XMillException *e = new XMillException(XMILL_ERR_ARGUMENTS, "Invalid parameter '");
738          e->ErrorCont(paramstr,len);
739          e->ErrorCont("' for compressor 'x'!");
740          throw e;
741       }*/
742    }
743    return new Base64Compressor(session, mindigits);
744 }
745 
InstantiateUncompressor(char * paramstr,int len)746 UserUncompressor *Base64CompressorFactory::InstantiateUncompressor(char *paramstr,int len)
747 {
748 /*   unsigned long mindigits=0;
749    if(paramstr!=NULL)
750    {
751       char savechar=paramstr[len];
752       paramstr[len]=0;
753       mindigits=atoi(paramstr);
754       paramstr[len]=savechar;
755       return new Base64Uncompressor(session, mindigits);
756    }
757    else*/
758       return &uncompressor;
759 }
760 
761