GTLRUtilities.m 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /* Copyright (c) 2011 Google Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. //#import <GoogleAPIClientForREST/GTLRUtilities.h>
  16. #import "GTLRUtilities.h"
  17. #include <objc/runtime.h>
  18. @implementation GTLRUtilities
  19. #pragma mark Key-Value Coding Searches in an Array
  20. + (NSArray *)objectsFromArray:(NSArray *)sourceArray
  21. withValue:(id)desiredValue
  22. forKeyPath:(NSString *)keyPath {
  23. // Step through all entries, get the value from
  24. // the key path, and see if it's equal to the
  25. // desired value
  26. NSMutableArray *results = [NSMutableArray array];
  27. for(id obj in sourceArray) {
  28. id val = [obj valueForKeyPath:keyPath];
  29. if (GTLR_AreEqualOrBothNil(val, desiredValue)) {
  30. // found a match; add it to the results array
  31. [results addObject:obj];
  32. }
  33. }
  34. return results;
  35. }
  36. + (id)firstObjectFromArray:(NSArray *)sourceArray
  37. withValue:(id)desiredValue
  38. forKeyPath:(NSString *)keyPath {
  39. for (id obj in sourceArray) {
  40. id val = [obj valueForKeyPath:keyPath];
  41. if (GTLR_AreEqualOrBothNil(val, desiredValue)) {
  42. // found a match; return it
  43. return obj;
  44. }
  45. }
  46. return nil;
  47. }
  48. #pragma mark Version helpers
  49. @end
  50. // isEqual: has the fatal flaw that it doesn't deal well with the receiver
  51. // being nil. We'll use this utility instead.
  52. BOOL GTLR_AreEqualOrBothNil(id obj1, id obj2) {
  53. if (obj1 == obj2) {
  54. return YES;
  55. }
  56. if (obj1 && obj2) {
  57. BOOL areEqual = [(NSObject *)obj1 isEqual:obj2];
  58. return areEqual;
  59. }
  60. return NO;
  61. }
  62. BOOL GTLR_AreBoolsEqual(BOOL b1, BOOL b2) {
  63. // avoid comparison problems with boolean types by negating
  64. // both booleans
  65. return (!b1 == !b2);
  66. }
  67. NSNumber *GTLR_EnsureNSNumber(NSNumber *num) {
  68. // If the server returned a string object where we expect a number, try
  69. // to make a number object.
  70. if ([num isKindOfClass:[NSString class]]) {
  71. NSNumber *newNum;
  72. NSString *str = (NSString *)num;
  73. if ([str rangeOfString:@"."].location != NSNotFound) {
  74. // This is a floating-point number.
  75. // Force the parser to use '.' as the decimal separator.
  76. static NSLocale *usLocale = nil;
  77. @synchronized([GTLRUtilities class]) {
  78. if (usLocale == nil) {
  79. usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
  80. }
  81. newNum = [NSDecimalNumber decimalNumberWithString:(NSString*)num
  82. locale:(id)usLocale];
  83. }
  84. } else {
  85. // NSDecimalNumber +decimalNumberWithString:locale:
  86. // does not correctly create an NSNumber for large values like
  87. // 71100000000007780.
  88. if ([str hasPrefix:@"-"]) {
  89. newNum = @([str longLongValue]);
  90. } else {
  91. const char *utf8 = str.UTF8String;
  92. unsigned long long ull = strtoull(utf8, NULL, 10);
  93. newNum = @(ull);
  94. }
  95. }
  96. if (newNum != nil) {
  97. num = newNum;
  98. }
  99. }
  100. return num;
  101. }