]> Dogcows Code - chaz/thecheat/blob - Variable.m
update contact information and project URL
[chaz/thecheat] / Variable.m
1
2 /*
3 * The Cheat - The legendary universal game trainer for Mac OS X.
4 * http://www.brokenzipper.com/trac/wiki/TheCheat
5 *
6 * Copyright (c) 2003-2011, Charles McGarvey et al.
7 *
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.
10 */
11
12 #import "Variable.h"
13
14 @interface Variable ( PrivateAPI )
15
16 - (void)_setType:(TCVariableType)type;
17 - (void)_setIntegerSign:(TCIntegerSign)sign;
18
19 @end
20
21
22 @implementation Variable
23
24
25 - (id)init
26 {
27 return [self initWithType:TCInt32 integerSign:TCSigned];
28 }
29
30 - (id)initWithType:(TCVariableType)type
31 {
32 return [self initWithType:type integerSign:TCSigned];
33 }
34
35 - (id)initWithType:(TCVariableType)type integerSign:(TCIntegerSign)sign // DESIGNATED
36 {
37 if ( self = [super init] ) {
38 _isValueValid = YES;
39 _enabled = YES;
40 [self _setType:type];
41 [self _setIntegerSign:sign];
42 }
43 return self;
44 }
45
46 - (void)setProcess:(Process *)newProcess
47 {
48 if (process != newProcess && [newProcess pid] > 0)
49 {
50 _isEmulated = [newProcess isEmulated];
51
52 [newProcess retain];
53 [process release];
54 process = newProcess;
55 }
56 }
57
58 - (Process *)process
59 {
60 return process;
61 }
62
63 - (BOOL)isEmulated
64 {
65 return _isEmulated;
66 }
67
68 - (void)dealloc
69 {
70 if ( _value ) {
71 free( _value );
72 }
73 [super dealloc];
74 }
75
76
77 // #############################################################################
78 #pragma mark NSCoding
79 // #############################################################################
80
81 - (id)initWithCoder:(NSCoder *)coder
82 {
83 if ( self = [super init] ) {
84 [coder decodeValueOfObjCType:@encode(TCVariableType) at:&_type];
85 [coder decodeValueOfObjCType:@encode(TCIntegerSign) at:&_integerSign];
86 [coder decodeValueOfObjCType:@encode(TCAddress) at:&_address];
87
88 void *value = [coder decodeBytesWithReturnedLength:&_size];
89
90 if (_type == TCString || _type == TCInt8)
91 {
92 [self setValue:value];
93 }
94 else if (_type == TCInt16)
95 {
96 int16_t newVariable = CFSwapInt16BigToHost(*((int16_t *)value));
97 [self setValue:&newVariable];
98 }
99 else if (_type == TCInt32)
100 {
101 int32_t newVariable = CFSwapInt32BigToHost(*((int32_t *)value));
102 [self setValue:&newVariable];
103 }
104 else if (_type == TCInt64)
105 {
106 int64_t newVariable = CFSwapInt64BigToHost(*((int64_t *)value));
107 [self setValue:&newVariable];
108 }
109 else if (_type == TCFloat)
110 {
111 #ifdef __LITTLE_ENDIAN__
112 CFSwappedFloat32 newVariable = CFConvertFloat32HostToSwapped(*((float *)value));
113 [self setValue:&(newVariable.v)];
114
115 #else
116 [self setValue:value];
117 #endif
118 }
119 else if (_type == TCDouble)
120 {
121 #ifdef __LITTLE_ENDIAN__
122 CFSwappedFloat64 newVariable = CFConvertDoubleHostToSwapped(*((double *)value));
123 [self setValue:&(newVariable.v)];
124 #else
125 [self setValue:value];
126 #endif
127 }
128
129 [coder decodeValueOfObjCType:@encode(BOOL) at:&_isValueValid];
130 [coder decodeValueOfObjCType:@encode(BOOL) at:&_enabled];
131 [coder decodeValueOfObjCType:@encode(int) at:&_tag];
132 }
133 return self;
134 }
135
136 - (void)encodeWithCoder:(NSCoder *)coder
137 {
138 [coder encodeValueOfObjCType:@encode(TCVariableType) at:&_type];
139 [coder encodeValueOfObjCType:@encode(TCIntegerSign) at:&_integerSign];
140 [coder encodeValueOfObjCType:@encode(TCAddress) at:&_address];
141
142 if (_type == TCString || _type == TCInt8)
143 {
144 [coder encodeBytes:_value length:_size];
145 }
146 else if (_type == TCInt16)
147 {
148 int16_t newVariable = CFSwapInt16HostToBig(*((int16_t *)_value));
149 [coder encodeBytes:&newVariable length:_size];
150 }
151 else if (_type == TCInt32)
152 {
153 int32_t newVariable = CFSwapInt32HostToBig(*((int32_t *)_value));
154 [coder encodeBytes:&newVariable length:_size];
155 }
156 else if (_type == TCInt64)
157 {
158 int64_t newVariable = CFSwapInt64HostToBig(*((int64_t *)_value));
159 [coder encodeBytes:&newVariable length:_size];
160 }
161 else if (_type == TCFloat)
162 {
163 #ifdef __LITTLE_ENDIAN__
164 CFSwappedFloat32 newVariable = CFConvertFloat32HostToSwapped(*((float *)_value));
165 [coder encodeBytes:&newVariable length:_size];
166 #else
167 [coder encodeBytes:&_value length:_size];
168 #endif
169 }
170 else if (_type == TCDouble)
171 {
172 #ifdef __LITTLE_ENDIAN__
173 CFSwappedFloat64 newVariable = CFConvertDoubleHostToSwapped(*((double *)_value));
174 [coder encodeBytes:&newVariable length:_size];
175 #else
176 [coder encodeBytes:_value length:_size];
177 #endif
178 }
179
180 [coder encodeValueOfObjCType:@encode(BOOL) at:&_isValueValid];
181 [coder encodeValueOfObjCType:@encode(BOOL) at:&_enabled];
182 [coder encodeValueOfObjCType:@encode(int) at:&_tag];
183 }
184
185
186 // #############################################################################
187 #pragma mark Accessors
188 // #############################################################################
189
190 - (TCVariableType)type
191 {
192 return _type;
193 }
194
195 - (void)_setType:(TCVariableType)type
196 {
197 _type = type;
198 // set the size of the value
199 switch ( _type ) {
200 case TCInt64:
201 case TCDouble: _size = 8;
202 break;
203 case TCInt32:
204 case TCFloat: _size = 4;
205 break;
206 case TCInt16: _size = 2;
207 break;
208 case TCInt8: _size = 1;
209 break;
210 }
211
212 if ( !_value ) {
213 _value = calloc( 1, _size );
214 }
215 }
216
217 - (TCIntegerSign)integerSign
218 {
219 return _integerSign;
220 }
221
222 - (void)_setIntegerSign:(TCIntegerSign)sign
223 {
224 _integerSign = sign;
225 }
226
227
228 - (NSString *)typeString
229 {
230 switch ( _type ) {
231 case TCDouble: return @"Double";
232 case TCFloat: return @"Float";
233 case TCString: return @"ASCII String";
234 }
235 if ( _integerSign == TCUnsigned ) {
236 switch ( _type ) {
237 case TCInt64: return @"64-bit Unsigned Integer";
238 case TCInt32: return @"32-bit Unsigned Integer";
239 case TCInt16: return @"16-bit Unsigned Integer";
240 case TCInt8: return @"08-bit Unsigned Integer";
241 }
242 }
243 else {
244 switch ( _type ) {
245 case TCInt64: return @"64-bit Integer";
246 case TCInt32: return @"32-bit Integer";
247 case TCInt16: return @"16-bit Integer";
248 case TCInt8: return @"08-bit Integer";
249 }
250 }
251 return @"";
252 }
253
254
255 - (TCAddress)address
256 {
257 return _address;
258 }
259
260 - (void)setAddress:(TCAddress)addr
261 {
262 _address = addr;
263 }
264
265
266 - (NSString *)addressString
267 {
268 // return [NSString stringWithFormat:@"%0.8X", _address];
269 return [NSString stringWithFormat:(_address & 0xffffffff00000000ULL) ? @"%0.16qX": @"%0.8X", _address];
270 }
271
272 - (BOOL)setAddressString:(NSString *)string
273 {
274 NSScanner *scanner = [NSScanner scannerWithString:string];
275 TCAddress address;
276
277 #if MAC_OS_X_VERSION_10_5 <= MAC_OS_X_VERSION_MAX_ALLOWED
278 if ( [scanner scanHexLongLong:(unsigned long long *)(&address)] ) {
279 #else
280 if ( [scanner scanHexInt:(unsigned *)(&address)] ) {
281 #endif
282 [self setAddress:address];
283 return YES;
284 }
285 return NO;
286 }
287
288
289 - (void const *)value
290 {
291 return _value;
292 }
293
294 - (void)setValue:(void const *)value
295 {
296 if ( !_value ) {
297 _value = malloc( _size );
298 }
299
300 _isValueValid = YES;
301 memcpy( _value, value, _size );
302 }
303
304 - (void)setValue:(void const *)value size:(unsigned)size
305 {
306 // make sure the size doesn't exceed the maximum
307 size = MIN( size, TC_MAX_VAR_SIZE );
308 // only string variables can have the value size changed
309 if ( (_type == TCString) && (_size != size) && _value ) {
310 void *newValue = realloc( _value, size );
311 if ( newValue ) {
312 _value = newValue;
313 _size = size;
314 }
315 }
316 _size = MIN( _size, size );
317
318 [self setValue:value];
319 }
320
321
322 - (NSString *)stringValue
323 {
324 switch ( _type ) {
325 case TCDouble: return [NSString stringWithFormat:@"%.1lf", *(double *)[self value]];
326 case TCFloat: return [NSString stringWithFormat:@"%.1f", *(float *)[self value]];
327 case TCString: return [NSString stringWithCString:[self value] length:[self valueSize]];
328 }
329 if ( _integerSign == TCUnsigned ) {
330 switch ( _type ) {
331 case TCInt64: return [NSString stringWithFormat:@"%llu", *(UInt64 *)[self value]];
332 case TCInt32: return [NSString stringWithFormat:@"%u", *(UInt32 *)[self value]];
333 case TCInt16: return [NSString stringWithFormat:@"%u", *(UInt16 *)[self value]];
334 case TCInt8: return [NSString stringWithFormat:@"%u", *(UInt8 *)[self value]];
335 }
336 }
337 else {
338 switch ( _type ) {
339 case TCInt64: return [NSString stringWithFormat:@"%lli", *(SInt64 *)[self value]];
340 case TCInt32: return [NSString stringWithFormat:@"%i", *(SInt32 *)[self value]];
341 case TCInt16: return [NSString stringWithFormat:@"%i", *(SInt16 *)[self value]];
342 case TCInt8: return [NSString stringWithFormat:@"%i", *(SInt8 *)[self value]];
343 }
344 }
345 return @"foobar";
346 }
347
348 - (BOOL)setStringValue:(NSString *)string
349 {
350 NSScanner *scanner = [NSScanner scannerWithString:string];
351
352 // invalid until proven valid
353 _isValueValid = NO;
354
355 switch ( _type ) {
356 case TCInt64:
357 {
358 SInt64 value;
359 if ( [scanner scanLongLong:(long long *)(&value)] ) {
360 [self setValue:&value];
361 }
362 break;
363 }
364 case TCInt32:
365 {
366 SInt32 value;
367 // if ( [scanner scanInt:(int *)(&value)] ) {
368 int integer;
369 if ( [scanner scanInt:&integer] ) {
370 value = integer;
371 [self setValue:&value];
372 }
373 break;
374 }
375 case TCInt16:
376 {
377 int integer;
378 SInt16 value;
379 if ( [scanner scanInt:&integer] ) {
380 value = integer;
381 [self setValue:&value];
382 }
383 break;
384 }
385 case TCInt8:
386 {
387 int integer;
388 SInt8 value;
389 if ( [scanner scanInt:&integer] ) {
390 value = integer;
391 [self setValue:&value];
392 }
393 break;
394 }
395 case TCString:
396 {
397 char *str = (char *)[string lossyCString];
398 unsigned len = strlen( str );
399 [self setValue:str size:len];
400 break;
401 }
402 case TCFloat:
403 {
404 float value;
405 if ( [scanner scanFloat:&value] ) {
406 [self setValue:&value];
407 }
408 break;
409 }
410 case TCDouble:
411 {
412 double value;
413 if ( [scanner scanDouble:&value] ) {
414 [self setValue:&value];
415 }
416 break;
417 }
418 }
419 return [self isValueValid];
420 }
421
422 // this only converts the byte order of the value at buffer if the process is running under rosetta on an intel mac
423 // floats and double's byte ordering should not be changed when searching for values because they may be swapped to '0.0'
424 void bigEndianValue(void *buffer, Variable *variable)
425 {
426 if (variable->_isEmulated)
427 {
428 if (variable->_type == TCInt16)
429 {
430 int16_t newValue = CFSwapInt16HostToBig(*((int16_t *)buffer));
431 memcpy(buffer, &newValue, sizeof(int16_t));
432 }
433 else if (variable->_type == TCInt32)
434 {
435 int32_t newValue = CFSwapInt32HostToBig(*((int32_t *)buffer));
436 memcpy(buffer, &newValue, sizeof(int32_t));
437 }
438 else if (variable->_type == TCInt64)
439 {
440 int64_t newValue = CFSwapInt64HostToBig(*((int64_t *)buffer));
441 memcpy(buffer, &newValue, sizeof(int64_t));
442 }
443 else if (variable->_type == TCFloat)
444 {
445 CFSwappedFloat32 newValue = CFConvertFloat32HostToSwapped(*((float *)buffer));
446 memcpy(buffer, &(newValue.v), sizeof(float));
447 }
448 else if (variable->_type == TCDouble)
449 {
450 CFSwappedFloat64 newValue = CFConvertDoubleHostToSwapped(*((double *)buffer));
451 memcpy(buffer, &(newValue.v), sizeof(double));
452 }
453 }
454 }
455
456 - (unsigned)valueSize
457 {
458 return _size;
459 }
460
461 - (BOOL)isValueValid
462 {
463 return _isValueValid;
464 }
465
466
467 - (BOOL)isEnabled
468 {
469 return _enabled;
470 }
471
472 - (void)setEnabled:(BOOL)enabled
473 {
474 _enabled = enabled;
475 }
476
477
478 #if MAC_OS_X_VERSION_10_5 <= MAC_OS_X_VERSION_MAX_ALLOWED
479 - (NSInteger)tag
480 #else
481 - (int)tag
482 #endif
483 {
484 return _tag;
485 }
486
487 #if MAC_OS_X_VERSION_10_5 <= MAC_OS_X_VERSION_MAX_ALLOWED
488 - (void)setTag:(NSInteger)tag
489 #else
490 - (void)setTag:(int)tag
491 #endif
492 {
493 _tag = tag;
494 }
495
496
497 @end
This page took 0.051437 seconds and 4 git commands to generate.