PageRenderTime 24ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/core/externals/google-toolbox-for-mac/Foundation/GTMNSScanner+JSON.m

http://macfuse.googlecode.com/
Objective C | 83 lines | 61 code | 3 blank | 19 comment | 19 complexity | be57e7afee3730cc332c19e8aa04a7d9 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, GPL-2.0
  1. //
  2. // GTMNSScanner+JSON.m
  3. //
  4. // Copyright 2009 Google Inc.
  5. //
  6. // Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7. // use this file except in compliance with the License. You may obtain a copy
  8. // of the License at
  9. //
  10. // http://www.apache.org/licenses/LICENSE-2.0
  11. //
  12. // Unless required by applicable law or agreed to in writing, software
  13. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  14. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  15. // License for the specific language governing permissions and limitations under
  16. // the License.
  17. //
  18. #import "GTMDefines.h"
  19. #import "GTMNSScanner+JSON.h"
  20. @implementation NSScanner (GTMNSScannerJSONAdditions)
  21. - (BOOL)gtm_scanJSONString:(NSString **)jsonString
  22. startChar:(unichar)startChar
  23. endChar:(unichar)endChar {
  24. BOOL isGood = NO;
  25. NSRange jsonRange = { NSNotFound, 0 };
  26. NSString *scanString = [self string];
  27. NSUInteger startLocation = [self scanLocation];
  28. NSUInteger length = [scanString length];
  29. NSUInteger blockOpen = 0;
  30. NSCharacterSet *charsToSkip = [self charactersToBeSkipped];
  31. BOOL inQuoteMode = NO;
  32. NSUInteger i;
  33. for (i = startLocation; i < length; ++i) {
  34. unichar jsonChar = [scanString characterAtIndex:i];
  35. if (jsonChar == startChar && !inQuoteMode) {
  36. if (blockOpen == 0) {
  37. jsonRange.location = i;
  38. }
  39. blockOpen += 1;
  40. } else if (blockOpen == 0) {
  41. // If we haven't opened our block skip over any characters in
  42. // charsToSkip.
  43. if (![charsToSkip characterIsMember:jsonChar]) {
  44. break;
  45. }
  46. } else if (jsonChar == endChar && !inQuoteMode) {
  47. blockOpen -= 1;
  48. if (blockOpen == 0) {
  49. i += 1; // Move onto next character
  50. jsonRange.length = i - jsonRange.location;
  51. break;
  52. }
  53. } else {
  54. if (jsonChar == '"') {
  55. inQuoteMode = !inQuoteMode;
  56. } else if (inQuoteMode && jsonChar == '\\') {
  57. // Skip the escaped character if it isn't the last one
  58. if (i < length - 1) ++i;
  59. }
  60. }
  61. }
  62. [self setScanLocation:i];
  63. if (blockOpen == 0 && jsonRange.location != NSNotFound) {
  64. isGood = YES;
  65. if (jsonString) {
  66. *jsonString = [scanString substringWithRange:jsonRange];
  67. }
  68. }
  69. return isGood;
  70. }
  71. - (BOOL)gtm_scanJSONObjectString:(NSString **)jsonString {
  72. return [self gtm_scanJSONString:jsonString startChar:'{' endChar:'}'];
  73. }
  74. - (BOOL)gtm_scanJSONArrayString:(NSString**)jsonString {
  75. return [self gtm_scanJSONString:jsonString startChar:'[' endChar:']'];
  76. }
  77. @end