]> Dogcows Code - chaz/thecheat/blob - Variable.m
Remove support of Mac OS X 10.3 and earlier system, change codes for Mac OS X 10.7.
[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 ( [scanner scanHexLongLong:(unsigned long long *)(&address)] ) {
278 [self setAddress:address];
279 return YES;
280 }
281 return NO;
282 }
283
284
285 - (void const *)value
286 {
287 return _value;
288 }
289
290 - (void)setValue:(void const *)value
291 {
292 if ( !_value ) {
293 _value = malloc( _size );
294 }
295
296 _isValueValid = YES;
297 memcpy( _value, value, _size );
298 }
299
300 - (void)setValue:(void const *)value size:(unsigned)size
301 {
302 // make sure the size doesn't exceed the maximum
303 size = MIN( size, TC_MAX_VAR_SIZE );
304 // only string variables can have the value size changed
305 if ( (_type == TCString) && (_size != size) && _value ) {
306 void *newValue = realloc( _value, size );
307 if ( newValue ) {
308 _value = newValue;
309 _size = size;
310 }
311 }
312 _size = MIN( _size, size );
313
314 [self setValue:value];
315 }
316
317
318 - (NSString *)stringValue
319 {
320 switch ( _type ) {
321 case TCDouble: return [NSString stringWithFormat:@"%.1lf", *(double *)[self value]];
322 case TCFloat: return [NSString stringWithFormat:@"%.1f", *(float *)[self value]];
323 case TCString: return [[[NSString alloc] initWithBytes:[self value] length:[self valueSize] encoding:NSUTF8StringEncoding] autorelease];
324 }
325 if ( _integerSign == TCUnsigned ) {
326 switch ( _type ) {
327 case TCInt64: return [NSString stringWithFormat:@"%llu", *(UInt64 *)[self value]];
328 case TCInt32: return [NSString stringWithFormat:@"%u", *(UInt32 *)[self value]];
329 case TCInt16: return [NSString stringWithFormat:@"%u", *(UInt16 *)[self value]];
330 case TCInt8: return [NSString stringWithFormat:@"%u", *(UInt8 *)[self value]];
331 }
332 }
333 else {
334 switch ( _type ) {
335 case TCInt64: return [NSString stringWithFormat:@"%lli", *(SInt64 *)[self value]];
336 case TCInt32: return [NSString stringWithFormat:@"%i", *(SInt32 *)[self value]];
337 case TCInt16: return [NSString stringWithFormat:@"%i", *(SInt16 *)[self value]];
338 case TCInt8: return [NSString stringWithFormat:@"%i", *(SInt8 *)[self value]];
339 }
340 }
341 return @"foobar";
342 }
343
344 - (BOOL)setStringValue:(NSString *)string
345 {
346 NSScanner *scanner = [NSScanner scannerWithString:string];
347
348 // invalid until proven valid
349 _isValueValid = NO;
350
351 switch ( _type ) {
352 case TCInt64:
353 {
354 SInt64 value;
355 if ( [scanner scanLongLong:(long long *)(&value)] ) {
356 [self setValue:&value];
357 }
358 break;
359 }
360 case TCInt32:
361 {
362 SInt32 value;
363 // if ( [scanner scanInt:(int *)(&value)] ) {
364 int integer;
365 if ( [scanner scanInt:&integer] ) {
366 value = integer;
367 [self setValue:&value];
368 }
369 break;
370 }
371 case TCInt16:
372 {
373 int integer;
374 SInt16 value;
375 if ( [scanner scanInt:&integer] ) {
376 value = integer;
377 [self setValue:&value];
378 }
379 break;
380 }
381 case TCInt8:
382 {
383 int integer;
384 SInt8 value;
385 if ( [scanner scanInt:&integer] ) {
386 value = integer;
387 [self setValue:&value];
388 }
389 break;
390 }
391 case TCString:
392 {
393 char *str = (char *)[string cStringUsingEncoding:NSUTF8StringEncoding];
394 unsigned len = strlen( str );
395 [self setValue:str size:len];
396 break;
397 }
398 case TCFloat:
399 {
400 float value;
401 if ( [scanner scanFloat:&value] ) {
402 [self setValue:&value];
403 }
404 break;
405 }
406 case TCDouble:
407 {
408 double value;
409 if ( [scanner scanDouble:&value] ) {
410 [self setValue:&value];
411 }
412 break;
413 }
414 }
415 return [self isValueValid];
416 }
417
418 // this only converts the byte order of the value at buffer if the process is running under rosetta on an intel mac
419 // floats and double's byte ordering should not be changed when searching for values because they may be swapped to '0.0'
420 void bigEndianValue(void *buffer, Variable *variable)
421 {
422 if (variable->_isEmulated)
423 {
424 if (variable->_type == TCInt16)
425 {
426 int16_t newValue = CFSwapInt16HostToBig(*((int16_t *)buffer));
427 memcpy(buffer, &newValue, sizeof(int16_t));
428 }
429 else if (variable->_type == TCInt32)
430 {
431 int32_t newValue = CFSwapInt32HostToBig(*((int32_t *)buffer));
432 memcpy(buffer, &newValue, sizeof(int32_t));
433 }
434 else if (variable->_type == TCInt64)
435 {
436 int64_t newValue = CFSwapInt64HostToBig(*((int64_t *)buffer));
437 memcpy(buffer, &newValue, sizeof(int64_t));
438 }
439 else if (variable->_type == TCFloat)
440 {
441 CFSwappedFloat32 newValue = CFConvertFloat32HostToSwapped(*((float *)buffer));
442 memcpy(buffer, &(newValue.v), sizeof(float));
443 }
444 else if (variable->_type == TCDouble)
445 {
446 CFSwappedFloat64 newValue = CFConvertDoubleHostToSwapped(*((double *)buffer));
447 memcpy(buffer, &(newValue.v), sizeof(double));
448 }
449 }
450 }
451
452 - (unsigned)valueSize
453 {
454 return _size;
455 }
456
457 - (BOOL)isValueValid
458 {
459 return _isValueValid;
460 }
461
462
463 - (BOOL)isEnabled
464 {
465 return _enabled;
466 }
467
468 - (void)setEnabled:(BOOL)enabled
469 {
470 _enabled = enabled;
471 }
472
473 - (NSInteger)tag
474 {
475 return _tag;
476 }
477
478
479 - (void)setTag:(NSInteger)tag
480 {
481 _tag = tag;
482 }
483
484
485 @end
This page took 0.05275 seconds and 4 git commands to generate.