3 * The Cheat - The legendary universal game trainer for Mac OS X.
4 * http://www.brokenzipper.com/trac/wiki/TheCheat
6 * Copyright (c) 2003-2011, Charles McGarvey et al.
8 * Distributable under the terms and conditions of the 2-clause BSD
9 * license; see the file COPYING for the legal text of the license.
17 * WARNING! BEWARE! WATCH OUT!
19 * This source code file makes use of goto jump statements. If goto statements
20 * are disagreeable to you, you may want to skip over this file or you face the
21 * possibility that you will be changed in a very deep and personal way.
23 * You have been warned.
27 /* Here are some handy functions used in this file. */
29 void ReportSearchProgress( ThreadedTask
*task
, unsigned iteration
, unsigned regions
, int *progress
)
31 int newProgress
= (iteration
* 100) / regions
;
32 if ( newProgress
> *progress
) {
33 *progress
= newProgress
;
34 [task reportProgress
:newProgress
];
40 * This is a real gem. I have no idea where I got this, but it is a wicked
41 * fast string searching algorithm. Hope it's not patented...
44 void *bmsearch( char *pat
, int m
, char *text
, int n
) {
45 int i
,j
,k
,skip
[ASIZE
];if(m
==0)return 0;
46 for(k
=0;k
<ASIZE
;k
++)skip
[k
]=m
;
47 for(k
=0;k
<m
-1;k
++)skip
[(int)pat
[k
]]=m
-k
-1;
48 for(k
=m
-1;k
<n
;k
+=skip
[(int)text
[k
]&(ASIZE
-1)]){
49 for(j
=m
-1,i
=k
;j
>=0&&text
[i
]==pat
[j
];j
--)i
--;
50 if(j
==-1)return(text
+i
+1);}
56 #pragma mark Search Functions
59 int SearchIteration( ThreadedTask
*task
, unsigned iteration
)
61 SearchContext
*context
= [task context
];
63 unsigned hitsPerRegion
= 0;
69 region
= VMNextRegionWithAttributes( context
->process
, context
->lastRegion
, VMREGION_READABLE | VMREGION_WRITABLE
);
70 if ( VMRegionIsNotNull( region
) ) {
72 if ( context
->bufferSize
< VMRegionSize( region
) ) {
73 char *buf
= realloc( context
->buffer
, VMRegionSize( region
) );
75 context
->buffer
= buf
;
76 context
->bufferSize
= VMRegionSize( region
);
83 if ( !VMRegionBytes( region
, context
->buffer
, &size
) ) {
87 ptr
= context
->buffer
;
88 top
= context
->buffer
+ VMRegionSize( region
);
89 offset
= VMRegionAddress( region
) - (TCAddress
)context
->buffer
;
92 char firstValue
[context
->value
->_size
];
93 memcpy(firstValue
, ptr
, context
->value
->_size
);
95 if (context
->value
->_isEmulated
)
97 if (context
->value
->_type
== TCFloat
)
99 CFSwappedFloat32 firstSwappedFloat
= CFConvertFloat32HostToSwapped(*((float *)firstValue
));
100 memcpy(firstValue
, &firstSwappedFloat
, context
->value
->_size
);
102 else if (context
->value
->_type
== TCDouble
)
104 CFSwappedFloat64 firstSwappedDouble
= CFConvertDoubleHostToSwapped(*((double *)firstValue
));
105 memcpy(firstValue
, &firstSwappedDouble
, context
->value
->_size
);
109 if ( context
->compareFunc(firstValue
,context
->value
->_value
) ) {
110 if ( context
->numberOfResults
>= TCArrayElementCount(context
->addresses
) ) {
111 TCArrayResize( context
->addresses
, TCArrayElementCount(context
->addresses
) + TC_BUFFER_SIZE
/ sizeof(TCAddress
) );
112 context
->addressPtr
= (TCAddress
*)TCArrayBytes(context
->addresses
) + context
->numberOfResults
;
114 if ( context
->numberOfResults
>= TCArrayElementCount(context
->values
) ) {
115 TCArrayResize( context
->values
, TCArrayElementCount(context
->values
) + TC_BUFFER_SIZE
/ TCArrayElementSize(context
->values
) );
116 context
->valuePtr
= TCArrayBytes(context
->values
) + context
->numberOfResults
* TCArrayElementSize(context
->values
);
119 *context
->addressPtr
= (TCAddress
)ptr
+ offset
;
120 memcpy( context
->valuePtr
, ptr
, TCArrayElementSize( context
->values
) );
122 context
->numberOfResults
++;
125 context
->addressPtr
++;
126 context
->valuePtr
+= TCArrayElementSize( context
->values
);
129 ptr
+= TCArrayElementSize( context
->values
);
133 if ( hitsPerRegion
> 0 ) {
134 TCAddress addr
= VMRegionAddress( region
);
135 unsigned index
= TCArrayElementCount( context
->regions
);
136 unsigned newsize
= index
+ 1;
138 TCArrayResize( context
->regions
, newsize
);
139 TCArrayResize( context
->perRegion
, newsize
);
141 TCArraySetElementAtIndex( context
->regions
, index
, &addr
);
142 TCArraySetElementAtIndex( context
->perRegion
, index
, &hitsPerRegion
);
145 ReportSearchProgress( task
, iteration
, context
->regionCount
, &context
->progress
);
147 context
->lastRegion
= region
;
151 free( context
->buffer
);
152 context
->buffer
= NULL
;
153 TCArrayResize( context
->addresses
, context
->numberOfResults
);
154 TCArrayResize( context
->values
, context
->numberOfResults
);
160 int SearchIterationAgain( ThreadedTask
*task
, unsigned iteration
)
162 SearchContext
*context
= [task context
];
164 unsigned hitsPerRegion
= 0;
170 if ( iteration
< TCArrayElementCount( context
->lastRegions
) ) {
172 context
->lastRegion
= VMMakeRegion( context
->process
, *(context
->lastRegionPtr
), 0 );
173 region
= VMNextRegionWithAttributes( context
->process
, context
->lastRegion
, VMREGION_READABLE | VMREGION_WRITABLE
);
174 if ( VMRegionIsNotNull( region
) ) {
175 if ( context
->bufferSize
< VMRegionSize( region
) ) {
176 char *buf
= realloc( context
->buffer
, VMRegionSize( region
) );
178 context
->buffer
= buf
;
179 context
->bufferSize
= VMRegionSize( region
);
186 if ( !VMRegionBytes( region
, context
->buffer
, &size
) ) {
190 top
= *context
->lastPerRegionPtr
;
192 for ( i
= 0; i
< top
; i
++ ) {
193 ptr
= (void *)((TCAddress
)context
->buffer
+ *context
->lastAddressPtr
- VMRegionAddress(region
));
195 char firstValue
[context
->value
->_size
];
196 memcpy(firstValue
, ptr
, context
->value
->_size
);
198 if (context
->value
->_isEmulated
)
200 if (context
->value
->_type
== TCFloat
)
202 CFSwappedFloat32 firstSwappedFloat
= CFConvertFloat32HostToSwapped(*((float *)firstValue
));
203 memcpy(firstValue
, &firstSwappedFloat
, context
->value
->_size
);
205 else if (context
->value
->_type
== TCDouble
)
207 CFSwappedFloat64 firstSwappedDouble
= CFConvertDoubleHostToSwapped(*((double *)firstValue
));
208 memcpy(firstValue
, &firstSwappedDouble
, context
->value
->_size
);
212 if (ptr
>= context
->buffer
&& context
->compareFunc(firstValue
,context
->value
->_value
)) {
213 if ( context
->numberOfResults
>= TCArrayElementCount(context
->addresses
) ) {
214 TCArrayResize( context
->addresses
, TCArrayElementCount(context
->addresses
) + TC_BUFFER_SIZE
/ sizeof(TCAddress
) );
215 context
->addressPtr
= (TCAddress
*)TCArrayBytes(context
->addresses
) + context
->numberOfResults
;
217 if ( context
->numberOfResults
>= TCArrayElementCount(context
->values
) ) {
218 TCArrayResize( context
->values
, TCArrayElementCount(context
->values
) + TC_BUFFER_SIZE
/ TCArrayElementSize(context
->values
) );
219 context
->valuePtr
= TCArrayBytes(context
->values
) + context
->numberOfResults
* TCArrayElementSize(context
->values
);
222 *context
->addressPtr
= *context
->lastAddressPtr
;
223 memcpy( context
->valuePtr
, ptr
, TCArrayElementSize( context
->values
) );
225 context
->numberOfResults
++;
228 context
->addressPtr
++;
229 context
->valuePtr
+= TCArrayElementSize( context
->values
);
232 context
->lastAddressPtr
++;
237 context
->lastRegionPtr
++;
238 context
->lastPerRegionPtr
++;
240 if ( hitsPerRegion
> 0 ) {
241 TCAddress addr
= VMRegionAddress( region
);
242 unsigned index
= TCArrayElementCount( context
->regions
);
243 unsigned newsize
= index
+ 1;
245 TCArrayResize( context
->regions
, newsize
);
246 TCArrayResize( context
->perRegion
, newsize
);
248 TCArraySetElementAtIndex( context
->regions
, index
, &addr
);
249 TCArraySetElementAtIndex( context
->perRegion
, index
, &hitsPerRegion
);
252 ReportSearchProgress( task
, iteration
, context
->regionCount
, &context
->progress
);
254 context
->lastRegion
= region
;
258 free( context
->buffer
);
259 context
->buffer
= NULL
;
260 TCArrayResize( context
->addresses
, context
->numberOfResults
);
261 TCArrayResize( context
->values
, context
->numberOfResults
);
267 int SearchIterationLastValue( ThreadedTask
*task
, unsigned iteration
)
269 SearchContext
*context
= [task context
];
271 unsigned hitsPerRegion
= 0;
277 if ( iteration
< TCArrayElementCount( context
->lastRegions
) ) {
279 context
->lastRegion
= VMMakeRegion( context
->process
, *(context
->lastRegionPtr
), 0 );
280 region
= VMNextRegionWithAttributes( context
->process
, context
->lastRegion
, VMREGION_READABLE | VMREGION_WRITABLE
);
281 if ( VMRegionIsNotNull( region
) ) {
283 if ( context
->bufferSize
< VMRegionSize( region
) ) {
284 char *buf
= realloc( context
->buffer
, VMRegionSize( region
) );
286 context
->buffer
= buf
;
287 context
->bufferSize
= VMRegionSize( region
);
294 if ( !VMRegionBytes( region
, context
->buffer
, &size
) ) {
298 top
= *context
->lastPerRegionPtr
;
300 for ( i
= 0; i
< top
; i
++ ) {
302 ptr
= (void *)((TCAddress
)context
->buffer
+ *context
->lastAddressPtr
- VMRegionAddress(region
));
303 if ( ptr
>= context
->buffer
&& context
->compareFunc(ptr
,context
->lastValuePtr
) ) {
304 if ( context
->numberOfResults
>= TCArrayElementCount(context
->addresses
) ) {
305 TCArrayResize( context
->addresses
, TCArrayElementCount(context
->addresses
) + TC_BUFFER_SIZE
/ sizeof(TCAddress
) );
306 context
->addressPtr
= (TCAddress
*)TCArrayBytes(context
->addresses
) + context
->numberOfResults
;
308 if ( context
->numberOfResults
>= TCArrayElementCount(context
->values
) ) {
309 TCArrayResize( context
->values
, TCArrayElementCount(context
->values
) + TC_BUFFER_SIZE
/ TCArrayElementSize(context
->values
) );
310 context
->valuePtr
= TCArrayBytes(context
->values
) + context
->numberOfResults
* TCArrayElementSize(context
->values
);
313 *context
->addressPtr
= *context
->lastAddressPtr
;
314 memcpy( context
->valuePtr
, ptr
, TCArrayElementSize(context
->values
) );
316 context
->numberOfResults
++;
319 context
->addressPtr
++;
320 context
->valuePtr
+= TCArrayElementSize(context
->values
);
323 context
->lastAddressPtr
++;
324 context
->lastValuePtr
+= TCArrayElementSize(context
->values
);
329 context
->lastRegionPtr
++;
330 context
->lastPerRegionPtr
++;
332 if ( hitsPerRegion
> 0 ) {
333 TCAddress addr
= VMRegionAddress( region
);
334 unsigned index
= TCArrayElementCount( context
->regions
);
335 unsigned newsize
= index
+ 1;
337 TCArrayResize( context
->regions
, newsize
);
338 TCArrayResize( context
->perRegion
, newsize
);
340 TCArraySetElementAtIndex( context
->regions
, index
, &addr
);
341 TCArraySetElementAtIndex( context
->perRegion
, index
, &hitsPerRegion
);
344 ReportSearchProgress( task
, iteration
, context
->regionCount
, &context
->progress
);
346 context
->lastRegion
= region
;
350 free( context
->buffer
);
351 context
->buffer
= NULL
;
352 TCArrayResize( context
->addresses
, context
->numberOfResults
);
353 TCArrayResize( context
->values
, context
->numberOfResults
);
360 int SearchStringIteration( ThreadedTask
*task
, unsigned iteration
)
362 SearchContext
*context
= [task context
];
364 unsigned hitsPerRegion
= 0;
367 void *ptr
, *top
, *hit
;
370 region
= VMNextRegionWithAttributes( context
->process
, context
->lastRegion
, VMREGION_READABLE | VMREGION_WRITABLE
);
371 if ( VMRegionIsNotNull( region
) ) {
373 if ( context
->bufferSize
< VMRegionSize(region
) ) {
374 char *buf
= realloc( context
->buffer
, VMRegionSize( region
) );
376 context
->buffer
= buf
;
377 context
->bufferSize
= VMRegionSize(region
);
384 if ( !VMRegionBytes( region
, context
->buffer
, &size
) ) {
388 ptr
= context
->buffer
;
389 top
= context
->buffer
+ VMRegionSize( region
);
390 offset
= VMRegionAddress( region
) - (TCAddress
)context
->buffer
;
393 hit
= bmsearch( context
->value
->_value
, context
->value
->_size
, ptr
, top
- ptr
);
395 if ( context
->numberOfResults
>= TCArrayElementCount(context
->addresses
) ) {
396 TCArrayResize( context
->addresses
, TCArrayElementCount(context
->addresses
) + TC_BUFFER_SIZE
/ sizeof(TCAddress
) );
397 context
->addressPtr
= (TCAddress
*)TCArrayBytes(context
->addresses
) + context
->numberOfResults
;
399 if ( context
->numberOfResults
>= TCArrayElementCount(context
->values
) ) {
400 TCArrayResize( context
->values
, TCArrayElementCount(context
->values
) + TC_BUFFER_SIZE
/ TCArrayElementSize(context
->values
) );
401 context
->valuePtr
= TCArrayBytes(context
->values
) + context
->numberOfResults
* TCArrayElementSize(context
->values
);
404 *context
->addressPtr
= (TCAddress
)hit
+ offset
;
405 memcpy( context
->valuePtr
, hit
, context
->value
->_size
);
406 context
->addressPtr
++;
407 context
->valuePtr
+= context
->value
->_size
;
409 context
->numberOfResults
++;
418 if ( hitsPerRegion
> 0 ) {
419 TCAddress addr
= VMRegionAddress( region
);
420 unsigned index
= TCArrayElementCount( context
->regions
);
421 unsigned newsize
= index
+ 1;
423 TCArrayResize( context
->regions
, newsize
);
424 TCArrayResize( context
->perRegion
, newsize
);
426 TCArraySetElementAtIndex( context
->regions
, index
, &addr
);
427 TCArraySetElementAtIndex( context
->perRegion
, index
, &hitsPerRegion
);
430 ReportSearchProgress( task
, iteration
, context
->regionCount
, &context
->progress
);
432 context
->lastRegion
= region
;
436 free( context
->buffer
);
437 context
->buffer
= NULL
;
438 TCArrayResize( context
->addresses
, context
->numberOfResults
);
439 TCArrayResize( context
->values
, context
->numberOfResults
);
444 int SearchStringIterationAgain( ThreadedTask
*task
, unsigned iteration
)
446 SearchContext
*context
= [task context
];
448 unsigned hitsPerRegion
= 0;
454 if ( iteration
< TCArrayElementCount( context
->lastRegions
) ) {
456 context
->lastRegion
= VMMakeRegion( context
->process
, *(context
->lastRegionPtr
), 0 );
457 region
= VMNextRegionWithAttributes( context
->process
, context
->lastRegion
, VMREGION_READABLE | VMREGION_WRITABLE
);
458 if ( VMRegionIsNotNull( region
) ) {
460 if ( context
->bufferSize
< VMRegionSize( region
) ) {
461 char *buf
= realloc( context
->buffer
, VMRegionSize( region
) );
463 context
->buffer
= buf
;
464 context
->bufferSize
= VMRegionSize( region
);
471 if ( !VMRegionBytes( region
, context
->buffer
, &size
) ) {
475 top
= *context
->lastPerRegionPtr
;
477 for ( i
= 0; i
< top
; i
++ ) {
479 ptr
= (void *)((TCAddress
)context
->buffer
+ *context
->lastAddressPtr
- VMRegionAddress(region
));
481 if ( ptr
>= context
->buffer
&& memcmp( ptr
, context
->value
->_value
, MIN(TCArrayElementSize(context
->values
),(TCAddress
)context
->buffer
+VMRegionAddress(region
)-(TCAddress
)ptr
) ) == 0 ) {
482 if ( context
->numberOfResults
>= TCArrayElementCount(context
->addresses
) ) {
483 TCArrayResize( context
->addresses
, TCArrayElementCount(context
->addresses
) + TC_BUFFER_SIZE
/ sizeof(TCAddress
) );
484 context
->addressPtr
= (TCAddress
*)TCArrayBytes(context
->addresses
) + context
->numberOfResults
;
486 if ( context
->numberOfResults
>= TCArrayElementCount(context
->values
) ) {
487 TCArrayResize( context
->values
, TCArrayElementCount(context
->values
) + TC_BUFFER_SIZE
/ TCArrayElementSize(context
->values
) );
488 context
->valuePtr
= TCArrayBytes(context
->values
) + context
->numberOfResults
* TCArrayElementSize(context
->values
);
491 *context
->addressPtr
= *context
->lastAddressPtr
;
492 memcpy( context
->valuePtr
, ptr
, TCArrayElementSize( context
->values
) );
493 context
->addressPtr
++;
494 context
->valuePtr
+= TCArrayElementSize( context
->values
);
496 context
->numberOfResults
++;
500 context
->lastAddressPtr
++;
505 context
->lastRegionPtr
++;
506 context
->lastPerRegionPtr
++;
508 if ( hitsPerRegion
> 0 ) {
509 TCAddress addr
= VMRegionAddress( region
);
510 unsigned index
= TCArrayElementCount( context
->regions
);
511 unsigned newsize
= index
+ 1;
513 TCArrayResize( context
->regions
, newsize
);
514 TCArrayResize( context
->perRegion
, newsize
);
516 TCArraySetElementAtIndex( context
->regions
, index
, &addr
);
517 TCArraySetElementAtIndex( context
->perRegion
, index
, &hitsPerRegion
);
520 ReportSearchProgress( task
, iteration
, context
->regionCount
, &context
->progress
);
522 context
->lastRegion
= region
;
526 free( context
->buffer
);
527 context
->buffer
= NULL
;
528 TCArrayResize( context
->addresses
, context
->numberOfResults
);
529 TCArrayResize( context
->values
, context
->numberOfResults
);
534 int SearchStringIterationLastValue( ThreadedTask
*task
, unsigned iteration
)
536 SearchContext
*context
= [task context
];
538 unsigned hitsPerRegion
= 0;
544 if ( iteration
< TCArrayElementCount( context
->lastRegions
) ) {
546 context
->lastRegion
= VMMakeRegion( context
->process
, *(context
->lastRegionPtr
), 0 );
547 region
= VMNextRegionWithAttributes( context
->process
, context
->lastRegion
, VMREGION_READABLE | VMREGION_WRITABLE
);
548 if ( VMRegionIsNotNull( region
) ) {
550 if ( context
->bufferSize
< VMRegionSize( region
) ) {
551 char *buf
= realloc( context
->buffer
, VMRegionSize( region
) );
553 context
->buffer
= buf
;
554 context
->bufferSize
= VMRegionSize( region
);
561 if ( !VMRegionBytes( region
, context
->buffer
, &size
) ) {
565 top
= *context
->lastPerRegionPtr
;
567 for ( i
= 0; i
< top
; i
++ ) {
569 ptr
= (void *)((TCAddress
)context
->buffer
+ *context
->lastAddressPtr
- VMRegionAddress(region
));
570 if ( ptr
>= context
->buffer
&& memcmp( ptr
, context
->lastValuePtr
, MIN(TCArrayElementSize(context
->values
),(TCAddress
)context
->buffer
+VMRegionAddress(region
)-(TCAddress
)ptr
) ) == 0 ) {
571 if ( context
->numberOfResults
>= TCArrayElementCount(context
->addresses
) ) {
572 TCArrayResize( context
->addresses
, TCArrayElementCount(context
->addresses
) + TC_BUFFER_SIZE
/ sizeof(TCAddress
) );
573 context
->addressPtr
= (TCAddress
*)TCArrayBytes(context
->addresses
) + context
->numberOfResults
;
575 if ( context
->numberOfResults
>= TCArrayElementCount(context
->values
) ) {
576 TCArrayResize( context
->values
, TCArrayElementCount(context
->values
) + TC_BUFFER_SIZE
/ TCArrayElementSize(context
->values
) );
577 context
->valuePtr
= TCArrayBytes(context
->values
) + context
->numberOfResults
* TCArrayElementSize(context
->values
);
580 *context
->addressPtr
= *context
->lastAddressPtr
;
581 memcpy( context
->valuePtr
, ptr
, TCArrayElementSize(context
->values
) );
582 context
->addressPtr
++;
583 context
->valuePtr
+= TCArrayElementSize(context
->values
);
585 context
->numberOfResults
++;
589 context
->lastAddressPtr
++;
590 context
->lastValuePtr
+= TCArrayElementSize(context
->lastValues
);
595 context
->lastRegionPtr
++;
596 context
->lastPerRegionPtr
++;
598 if ( hitsPerRegion
> 0 ) {
599 TCAddress addr
= VMRegionAddress( region
);
600 unsigned index
= TCArrayElementCount( context
->regions
);
601 unsigned newsize
= index
+ 1;
603 TCArrayResize( context
->regions
, newsize
);
604 TCArrayResize( context
->perRegion
, newsize
);
606 TCArraySetElementAtIndex( context
->regions
, index
, &addr
);
607 TCArraySetElementAtIndex( context
->perRegion
, index
, &hitsPerRegion
);
610 ReportSearchProgress( task
, iteration
, context
->regionCount
, &context
->progress
);
612 context
->lastRegion
= region
;
616 free( context
->buffer
);
617 context
->buffer
= NULL
;
618 TCArrayResize( context
->addresses
, context
->numberOfResults
);
619 TCArrayResize( context
->values
, context
->numberOfResults
);
627 #pragma mark Comparison Functions
631 BOOL EqualInt64( void const *first
, void const *second
) {
632 return *(SInt64
*)first
== *(SInt64
*)second
;
634 BOOL EqualInt32( void const *first
, void const *second
) {
635 return *(SInt32
*)first
== *(SInt32
*)second
;
637 BOOL EqualInt16( void const *first
, void const *second
) {
638 return *(SInt16
*)first
== *(SInt16
*)second
;
640 BOOL EqualInt8( void const *first
, void const *second
) {
641 return *(SInt8
*)first
== *(SInt8
*)second
;
643 BOOL EqualUInt64( void const *first
, void const *second
) {
644 return *(UInt64
*)first
== *(UInt64
*)second
;
646 BOOL EqualUInt32( void const *first
, void const *second
) {
647 return *(UInt32
*)first
== *(UInt32
*)second
;
649 BOOL EqualUInt16( void const *first
, void const *second
) {
650 return *(UInt16
*)first
== *(UInt16
*)second
;
652 BOOL EqualUInt8( void const *first
, void const *second
) {
653 return *(UInt8
*)first
== *(UInt8
*)second
;
655 BOOL EqualFloat( void const *first
, void const *second
) {
656 return TC_EPSILON
> ABS( *(float *)first
- *(float *)second
);
658 BOOL EqualDouble( void const *first
, void const *second
) {
659 return TC_EPSILON
> ABS( *(double *)first
- *(double *)second
);
662 BOOL NotEqualInt64( void const *first
, void const *second
) {
663 return *(SInt64
*)first
!= *(SInt64
*)second
;
665 BOOL NotEqualInt32( void const *first
, void const *second
) {
666 return *(SInt32
*)first
!= *(SInt32
*)second
;
668 BOOL NotEqualInt16( void const *first
, void const *second
) {
669 return *(SInt16
*)first
!= *(SInt16
*)second
;
671 BOOL NotEqualInt8( void const *first
, void const *second
) {
672 return *(SInt8
*)first
!= *(SInt8
*)second
;
674 BOOL NotEqualUInt64( void const *first
, void const *second
) {
675 return *(UInt64
*)first
!= *(UInt64
*)second
;
677 BOOL NotEqualUInt32( void const *first
, void const *second
) {
678 return *(UInt32
*)first
!= *(UInt32
*)second
;
680 BOOL NotEqualUInt16( void const *first
, void const *second
) {
681 return *(UInt16
*)first
!= *(UInt16
*)second
;
683 BOOL NotEqualUInt8( void const *first
, void const *second
) {
684 return *(UInt8
*)first
!= *(UInt8
*)second
;
686 BOOL NotEqualFloat( void const *first
, void const *second
) {
687 return TC_EPSILON
<= ABS( *(float *)first
- *(float *)second
);
689 BOOL NotEqualDouble( void const *first
, void const *second
) {
690 return TC_EPSILON
<= ABS( *(double *)first
- *(double *)second
);
693 BOOL LessThanInt64( void const *first
, void const *second
) {
694 return *(SInt64
*)first
< *(SInt64
*)second
;
696 BOOL LessThanInt32( void const *first
, void const *second
) {
697 return *(SInt32
*)first
< *(SInt32
*)second
;
699 BOOL LessThanInt16( void const *first
, void const *second
) {
700 return *(SInt16
*)first
< *(SInt16
*)second
;
702 BOOL LessThanInt8( void const *first
, void const *second
) {
703 return *(SInt8
*)first
< *(SInt8
*)second
;
705 BOOL LessThanUInt64( void const *first
, void const *second
) {
706 return *(UInt64
*)first
< *(UInt64
*)second
;
708 BOOL LessThanUInt32( void const *first
, void const *second
) {
709 return *(UInt32
*)first
< *(UInt32
*)second
;
711 BOOL LessThanUInt16( void const *first
, void const *second
) {
712 return *(UInt16
*)first
< *(UInt16
*)second
;
714 BOOL LessThanUInt8( void const *first
, void const *second
) {
715 return *(UInt8
*)first
< *(UInt8
*)second
;
717 BOOL LessThanFloat( void const *first
, void const *second
) {
718 return *(float *)first
< *(float *)second
;
720 BOOL LessThanDouble( void const *first
, void const *second
) {
721 return *(double *)first
< *(double *)second
;
724 BOOL GreaterThanInt64( void const *first
, void const *second
) {
725 return *(SInt64
*)first
> *(SInt64
*)second
;
727 BOOL GreaterThanInt32( void const *first
, void const *second
) {
728 return *(SInt32
*)first
> *(SInt32
*)second
;
730 BOOL GreaterThanInt16( void const *first
, void const *second
) {
731 return *(SInt16
*)first
> *(SInt16
*)second
;
733 BOOL GreaterThanInt8( void const *first
, void const *second
) {
734 return *(SInt8
*)first
> *(SInt8
*)second
;
736 BOOL GreaterThanUInt64( void const *first
, void const *second
) {
737 return *(UInt64
*)first
> *(UInt64
*)second
;
739 BOOL GreaterThanUInt32( void const *first
, void const *second
) {
740 return *(UInt32
*)first
> *(UInt32
*)second
;
742 BOOL GreaterThanUInt16( void const *first
, void const *second
) {
743 return *(UInt16
*)first
> *(UInt16
*)second
;
745 BOOL GreaterThanUInt8( void const *first
, void const *second
) {
746 return *(UInt8
*)first
> *(UInt8
*)second
;
748 BOOL GreaterThanFloat( void const *first
, void const *second
) {
749 return *(float *)first
> *(float *)second
;
751 BOOL GreaterThanDouble( void const *first
, void const *second
) {
752 return *(double *)first
> *(double *)second
;