common.m 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #import "common.h"
  2. // Copyright (c) 2008-2010, Vincent Gable.
  3. // http://vincentgable.com
  4. //
  5. // Use of this code permitted by copyright holder in this statement:
  6. // http://vgable.com/blog/2010/08/19/the-most-useful-objective-c-code-ive-
  7. // ever-written/
  8. //
  9. // based off
  10. // http://www.dribin.org/dave/blog/archives/2008/09/22/convert_to_nsstring/
  11. //
  12. static BOOL TypeCodeIsCharArray(const char *typeCode){
  13. size_t lastCharOffset = strlen(typeCode) - 1;
  14. size_t secondToLastCharOffset = lastCharOffset - 1 ;
  15. BOOL isCharArray = typeCode[0] == '[' &&
  16. typeCode[secondToLastCharOffset] == 'c' && typeCode[lastCharOffset] == ']';
  17. for(int i = 1; i < secondToLastCharOffset; i++)
  18. isCharArray = isCharArray && isdigit(typeCode[i]);
  19. return isCharArray;
  20. }
  21. //since BOOL is #defined as a signed char, we treat the value as
  22. //a BOOL if it is exactly YES or NO, and a char otherwise.
  23. static NSString* VTPGStringFromBoolOrCharValue(BOOL boolOrCharvalue) {
  24. if(boolOrCharvalue == YES)
  25. return @"YES";
  26. if(boolOrCharvalue == NO)
  27. return @"NO";
  28. return [NSString stringWithFormat:@"'%c'", boolOrCharvalue];
  29. }
  30. static NSString *VTPGStringFromFourCharCodeOrUnsignedInt32(FourCharCode fourcc) {
  31. return [NSString stringWithFormat:@"%u ('%c%c%c%c')",
  32. fourcc,
  33. (fourcc >> 24) & 0xFF,
  34. (fourcc >> 16) & 0xFF,
  35. (fourcc >> 8) & 0xFF,
  36. fourcc & 0xFF];
  37. }
  38. static NSString *StringFromNSDecimalWithCurrentLocal(NSDecimal dcm) {
  39. return NSDecimalString(&dcm, [NSLocale currentLocale]);
  40. }
  41. NSString * VTPG_DDToStringFromTypeAndValue(const char * typeCode, void * value) {
  42. #define IF_TYPE_MATCHES_INTERPRET_WITH(typeToMatch,func) \
  43. if (strcmp(typeCode, @encode(typeToMatch)) == 0) \
  44. return (func)(*(typeToMatch*)value)
  45. #if TARGET_OS_IPHONE
  46. IF_TYPE_MATCHES_INTERPRET_WITH(CGPoint,NSStringFromCGPoint);
  47. IF_TYPE_MATCHES_INTERPRET_WITH(CGSize,NSStringFromCGSize);
  48. IF_TYPE_MATCHES_INTERPRET_WITH(CGRect,NSStringFromCGRect);
  49. #else
  50. IF_TYPE_MATCHES_INTERPRET_WITH(NSPoint,NSStringFromPoint);
  51. IF_TYPE_MATCHES_INTERPRET_WITH(NSSize,NSStringFromSize);
  52. IF_TYPE_MATCHES_INTERPRET_WITH(NSRect,NSStringFromRect);
  53. #endif
  54. IF_TYPE_MATCHES_INTERPRET_WITH(NSRange,NSStringFromRange);
  55. IF_TYPE_MATCHES_INTERPRET_WITH(Class,NSStringFromClass);
  56. IF_TYPE_MATCHES_INTERPRET_WITH(SEL,NSStringFromSelector);
  57. IF_TYPE_MATCHES_INTERPRET_WITH(BOOL,VTPGStringFromBoolOrCharValue);
  58. IF_TYPE_MATCHES_INTERPRET_WITH(NSDecimal,StringFromNSDecimalWithCurrentLocal);
  59. #define IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(typeToMatch,formatString) \
  60. if (strcmp(typeCode, @encode(typeToMatch)) == 0) \
  61. return [NSString stringWithFormat:(formatString), (*(typeToMatch*)value)]
  62. IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(CFStringRef,@"%@"); //CFStringRef is toll-free bridged to NSString*
  63. IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(CFArrayRef,@"%@"); //CFArrayRef is toll-free bridged to NSArray*
  64. IF_TYPE_MATCHES_INTERPRET_WITH(FourCharCode, VTPGStringFromFourCharCodeOrUnsignedInt32);
  65. IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(long long,@"%lld");
  66. IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(unsigned long long,@"%llu");
  67. IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(float,@"%f");
  68. IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(double,@"%f");
  69. // IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(id,@"%@");
  70. IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(short,@"%hi");
  71. IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(unsigned short,@"%hu");
  72. IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(int,@"%i");
  73. IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(unsigned, @"%u");
  74. IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(long,@"%li");
  75. IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(long double,@"%Lf"); //WARNING on older versions of OS X, @encode(long double) == @encode(double)
  76. //C-strings
  77. IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(char*, @"%s");
  78. IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(const char*, @"%s");
  79. if(TypeCodeIsCharArray(typeCode))
  80. return [NSString stringWithFormat:@"%s", (char*)value];
  81. IF_TYPE_MATCHES_INTERPRET_WITH_FORMAT(void*,@"(void*)%p");
  82. //This is a hack to print out CLLocationCoordinate2D, without needing to #import <CoreLocation/CoreLocation.h>
  83. //A CLLocationCoordinate2D is a struct made up of 2 doubles.
  84. //We detect it by hard-coding the result of @encode(CLLocationCoordinate2D).
  85. //We get at the fields by treating it like an array of doubles, which it is identical to in memory.
  86. if(strcmp(typeCode, "{?=dd}")==0)//@encode(CLLocationCoordinate2D)
  87. return [NSString stringWithFormat:@"{latitude=%g,longitude=%g}",((double*)value)[0],((double*)value)[1]];
  88. //we don't know how to convert this typecode into an NSString
  89. return nil;
  90. }