iCuke 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. data/.gitmodules +1 -1
  2. data/Gemfile +12 -0
  3. data/Gemfile.lock +41 -0
  4. data/README.markdown +126 -0
  5. data/Rakefile +34 -12
  6. data/VERSION +1 -1
  7. data/bin/icuke +12 -10
  8. data/ext/Rakefile +6 -0
  9. data/ext/iCuke/{sdk3.1/DefaultsResponse.h → DefaultsResponse.h} +0 -0
  10. data/ext/iCuke/{sdk3.1/DefaultsResponse.m → DefaultsResponse.m} +0 -0
  11. data/ext/iCuke/{sdk3.1/EventResponse.h → EventResponse.h} +0 -0
  12. data/ext/iCuke/{sdk3.1/EventResponse.m → EventResponse.m} +0 -0
  13. data/ext/iCuke/{sdk3.1/ModuleResponse.h → ModuleResponse.h} +0 -0
  14. data/ext/iCuke/{sdk3.1/ModuleResponse.m → ModuleResponse.m} +0 -0
  15. data/ext/iCuke/{sdk3.1/QuitResponse.h → QuitResponse.h} +0 -0
  16. data/ext/iCuke/{sdk3.1/QuitResponse.m → QuitResponse.m} +0 -0
  17. data/ext/iCuke/Rakefile +14 -13
  18. data/ext/iCuke/{sdk3.1/Recorder.h → Recorder.h} +0 -0
  19. data/ext/iCuke/{sdk3.1/Recorder.m → Recorder.m} +0 -0
  20. data/ext/iCuke/{sdk3.1/RecorderResponse.h → RecorderResponse.h} +0 -0
  21. data/ext/iCuke/{sdk3.1/RecorderResponse.m → RecorderResponse.m} +0 -0
  22. data/ext/iCuke/{sdk3.1/SynthesizeSingleton.h → SynthesizeSingleton.h} +0 -0
  23. data/ext/iCuke/{sdk3.1/ViewResponse.h → ViewResponse.h} +0 -0
  24. data/ext/iCuke/{sdk3.1/ViewResponse.m → ViewResponse.m} +0 -0
  25. data/ext/iCuke/{sdk3.1/Viewer.h → Viewer.h} +0 -0
  26. data/ext/iCuke/{sdk4.0/Viewer.m → Viewer.m} +0 -0
  27. data/ext/iCuke/{sdk3.1/iCukeHTTPResponseHandler.h → iCukeHTTPResponseHandler.h} +0 -0
  28. data/ext/iCuke/{sdk3.1/iCukeHTTPResponseHandler.m → iCukeHTTPResponseHandler.m} +0 -0
  29. data/ext/iCuke/{sdk3.1/iCukeHTTPServer.h → iCukeHTTPServer.h} +0 -0
  30. data/ext/iCuke/{sdk4.0/iCukeHTTPServer.m → iCukeHTTPServer.m} +4 -2
  31. data/ext/iCuke/{sdk3.1/iCukeServer.h → iCukeServer.h} +0 -0
  32. data/ext/iCuke/{sdk3.1/iCukeServer.m → iCukeServer.m} +0 -0
  33. data/ext/iCuke/{sdk3.1/json → json}/JSON.h +0 -0
  34. data/ext/iCuke/{sdk3.1/json → json}/NSObject+SBJSON.h +0 -0
  35. data/ext/iCuke/{sdk3.1/json → json}/NSObject+SBJSON.m +0 -0
  36. data/ext/iCuke/{sdk3.1/json → json}/NSString+SBJSON.h +0 -0
  37. data/ext/iCuke/{sdk3.1/json → json}/NSString+SBJSON.m +0 -0
  38. data/ext/iCuke/{sdk3.1/json → json}/SBJSON.h +0 -0
  39. data/ext/iCuke/{sdk3.1/json → json}/SBJSON.m +0 -0
  40. data/ext/iCuke/{sdk3.1/json → json}/SBJsonBase.h +0 -0
  41. data/ext/iCuke/{sdk3.1/json → json}/SBJsonBase.m +0 -0
  42. data/ext/iCuke/{sdk3.1/json → json}/SBJsonParser.h +0 -0
  43. data/ext/iCuke/{sdk3.1/json → json}/SBJsonParser.m +0 -0
  44. data/ext/iCuke/{sdk3.1/json → json}/SBJsonWriter.h +0 -0
  45. data/ext/iCuke/{sdk3.1/json → json}/SBJsonWriter.m +0 -0
  46. data/features/starting_project.feature +18 -0
  47. data/features/step_definitions/shell.rb +41 -0
  48. data/features/support/env.rb +2 -0
  49. data/features/support/environment.rb +40 -0
  50. data/features/supported_sdks.feature +12 -0
  51. data/iCuke.gemspec +149 -161
  52. data/lib/icuke/configuration.rb +19 -0
  53. data/lib/icuke/core_ext.rb +27 -0
  54. data/lib/icuke/cucumber.rb +29 -265
  55. data/lib/icuke/cucumber_compat.rb +4 -0
  56. data/lib/icuke/icuke_world.rb +149 -0
  57. data/lib/icuke/sdk.rb +5 -13
  58. data/lib/icuke/simulator_driver.rb +201 -0
  59. data/lib/icuke/waxsim.rb +47 -9
  60. data/spec/cucumber_spec.rb +130 -0
  61. data/spec/fixtures/controls_page.xml +252 -0
  62. data/spec/process_spec.rb +76 -0
  63. data/spec/screen_spec.rb +173 -0
  64. data/spec/simulate_spec.rb +75 -0
  65. data/spec/simulator_spec.rb +28 -0
  66. data/spec/spec.opts +2 -0
  67. data/spec/spec_helper.rb +67 -0
  68. metadata +222 -121
  69. data/.gitignore +0 -15
  70. data/README.rdoc +0 -68
  71. data/ext/WaxSim/Simulator.h +0 -31
  72. data/ext/WaxSim/Simulator.m +0 -131
  73. data/ext/WaxSim/WaxSim.m +0 -110
  74. data/ext/WaxSim/WaxSim.xcodeproj/project.pbxproj +0 -238
  75. data/ext/WaxSim/WaxSim_Prefix.pch +0 -7
  76. data/ext/WaxSim/build/Release/waxsim +0 -0
  77. data/ext/WaxSim/build/Release/waxsim.dSYM/Contents/Info.plist +0 -20
  78. data/ext/WaxSim/build/Release/waxsim.dSYM/Contents/Resources/DWARF/waxsim +0 -0
  79. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/Objects-normal/x86_64/Simulator.o +0 -0
  80. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/Objects-normal/x86_64/WaxSim.o +0 -0
  81. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/Objects-normal/x86_64/waxsim.LinkFileList +0 -2
  82. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/WaxSim.dep +0 -6
  83. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/WaxSim~.dep +0 -6
  84. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/build-state.dat +0 -227
  85. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/build-state~.dat +0 -227
  86. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/waxsim-all-target-headers.hmap +0 -0
  87. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/waxsim-generated-files.hmap +0 -0
  88. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/waxsim-own-target-headers.hmap +0 -0
  89. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/waxsim-project-headers.hmap +0 -0
  90. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/waxsim.hmap +0 -0
  91. data/ext/WaxSim/iPhoneSimulatorRemoteClient/iPhoneSimulatorRemoteClient.h +0 -126
  92. data/ext/iCuke/sdk3.1/Rakefile +0 -20
  93. data/ext/iCuke/sdk3.1/Viewer.m +0 -203
  94. data/ext/iCuke/sdk3.1/iCukeHTTPServer.m +0 -365
  95. data/ext/iCuke/sdk4.0/DefaultsResponse.h +0 -5
  96. data/ext/iCuke/sdk4.0/DefaultsResponse.m +0 -66
  97. data/ext/iCuke/sdk4.0/EventResponse.h +0 -5
  98. data/ext/iCuke/sdk4.0/EventResponse.m +0 -130
  99. data/ext/iCuke/sdk4.0/ModuleResponse.h +0 -5
  100. data/ext/iCuke/sdk4.0/ModuleResponse.m +0 -76
  101. data/ext/iCuke/sdk4.0/QuitResponse.h +0 -5
  102. data/ext/iCuke/sdk4.0/QuitResponse.m +0 -23
  103. data/ext/iCuke/sdk4.0/Rakefile +0 -20
  104. data/ext/iCuke/sdk4.0/Recorder.h +0 -17
  105. data/ext/iCuke/sdk4.0/Recorder.m +0 -90
  106. data/ext/iCuke/sdk4.0/RecorderResponse.h +0 -6
  107. data/ext/iCuke/sdk4.0/RecorderResponse.m +0 -68
  108. data/ext/iCuke/sdk4.0/SynthesizeSingleton.h +0 -68
  109. data/ext/iCuke/sdk4.0/ViewResponse.h +0 -5
  110. data/ext/iCuke/sdk4.0/ViewResponse.m +0 -84
  111. data/ext/iCuke/sdk4.0/Viewer.h +0 -8
  112. data/ext/iCuke/sdk4.0/iCukeHTTPResponseHandler.h +0 -50
  113. data/ext/iCuke/sdk4.0/iCukeHTTPResponseHandler.m +0 -381
  114. data/ext/iCuke/sdk4.0/iCukeHTTPServer.h +0 -53
  115. data/ext/iCuke/sdk4.0/iCukeServer.h +0 -14
  116. data/ext/iCuke/sdk4.0/iCukeServer.m +0 -65
  117. data/ext/iCuke/sdk4.0/json/JSON.h +0 -50
  118. data/ext/iCuke/sdk4.0/json/NSObject+SBJSON.h +0 -68
  119. data/ext/iCuke/sdk4.0/json/NSObject+SBJSON.m +0 -53
  120. data/ext/iCuke/sdk4.0/json/NSString+SBJSON.h +0 -58
  121. data/ext/iCuke/sdk4.0/json/NSString+SBJSON.m +0 -55
  122. data/ext/iCuke/sdk4.0/json/SBJSON.h +0 -75
  123. data/ext/iCuke/sdk4.0/json/SBJSON.m +0 -212
  124. data/ext/iCuke/sdk4.0/json/SBJsonBase.h +0 -86
  125. data/ext/iCuke/sdk4.0/json/SBJsonBase.m +0 -78
  126. data/ext/iCuke/sdk4.0/json/SBJsonParser.h +0 -87
  127. data/ext/iCuke/sdk4.0/json/SBJsonParser.m +0 -475
  128. data/ext/iCuke/sdk4.0/json/SBJsonWriter.h +0 -129
  129. data/ext/iCuke/sdk4.0/json/SBJsonWriter.m +0 -228
@@ -1,475 +0,0 @@
1
- /*
2
- Copyright (C) 2009 Stig Brautaset. All rights reserved.
3
-
4
- Redistribution and use in source and binary forms, with or without
5
- modification, are permitted provided that the following conditions are met:
6
-
7
- * Redistributions of source code must retain the above copyright notice, this
8
- list of conditions and the following disclaimer.
9
-
10
- * Redistributions in binary form must reproduce the above copyright notice,
11
- this list of conditions and the following disclaimer in the documentation
12
- and/or other materials provided with the distribution.
13
-
14
- * Neither the name of the author nor the names of its contributors may be used
15
- to endorse or promote products derived from this software without specific
16
- prior written permission.
17
-
18
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
- */
29
-
30
- #import "SBJsonParser.h"
31
-
32
- @interface SBJsonParser ()
33
-
34
- - (BOOL)scanValue:(NSObject **)o;
35
-
36
- - (BOOL)scanRestOfArray:(NSMutableArray **)o;
37
- - (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o;
38
- - (BOOL)scanRestOfNull:(NSNull **)o;
39
- - (BOOL)scanRestOfFalse:(NSNumber **)o;
40
- - (BOOL)scanRestOfTrue:(NSNumber **)o;
41
- - (BOOL)scanRestOfString:(NSMutableString **)o;
42
-
43
- // Cannot manage without looking at the first digit
44
- - (BOOL)scanNumber:(NSNumber **)o;
45
-
46
- - (BOOL)scanHexQuad:(unichar *)x;
47
- - (BOOL)scanUnicodeChar:(unichar *)x;
48
-
49
- - (BOOL)scanIsAtEnd;
50
-
51
- @end
52
-
53
- #define skipWhitespace(c) while (isspace(*c)) c++
54
- #define skipDigits(c) while (isdigit(*c)) c++
55
-
56
-
57
- @implementation SBJsonParser
58
-
59
- static char ctrl[0x22];
60
-
61
- + (void)initialize
62
- {
63
- ctrl[0] = '\"';
64
- ctrl[1] = '\\';
65
- for (int i = 1; i < 0x20; i++)
66
- ctrl[i+1] = i;
67
- ctrl[0x21] = 0;
68
- }
69
-
70
- /**
71
- @deprecated This exists in order to provide fragment support in older APIs in one more version.
72
- It should be removed in the next major version.
73
- */
74
- - (id)fragmentWithString:(id)repr {
75
- [self clearErrorTrace];
76
-
77
- if (!repr) {
78
- [self addErrorWithCode:EINPUT description:@"Input was 'nil'"];
79
- return nil;
80
- }
81
-
82
- depth = 0;
83
- c = [repr UTF8String];
84
-
85
- id o;
86
- if (![self scanValue:&o]) {
87
- return nil;
88
- }
89
-
90
- // We found some valid JSON. But did it also contain something else?
91
- if (![self scanIsAtEnd]) {
92
- [self addErrorWithCode:ETRAILGARBAGE description:@"Garbage after JSON"];
93
- return nil;
94
- }
95
-
96
- NSAssert1(o, @"Should have a valid object from %@", repr);
97
- return o;
98
- }
99
-
100
- - (id)objectWithString:(NSString *)repr {
101
-
102
- id o = [self fragmentWithString:repr];
103
- if (!o)
104
- return nil;
105
-
106
- // Check that the object we've found is a valid JSON container.
107
- if (![o isKindOfClass:[NSDictionary class]] && ![o isKindOfClass:[NSArray class]]) {
108
- [self addErrorWithCode:EFRAGMENT description:@"Valid fragment, but not JSON"];
109
- return nil;
110
- }
111
-
112
- return o;
113
- }
114
-
115
- /*
116
- In contrast to the public methods, it is an error to omit the error parameter here.
117
- */
118
- - (BOOL)scanValue:(NSObject **)o
119
- {
120
- skipWhitespace(c);
121
-
122
- switch (*c++) {
123
- case '{':
124
- return [self scanRestOfDictionary:(NSMutableDictionary **)o];
125
- break;
126
- case '[':
127
- return [self scanRestOfArray:(NSMutableArray **)o];
128
- break;
129
- case '"':
130
- return [self scanRestOfString:(NSMutableString **)o];
131
- break;
132
- case 'f':
133
- return [self scanRestOfFalse:(NSNumber **)o];
134
- break;
135
- case 't':
136
- return [self scanRestOfTrue:(NSNumber **)o];
137
- break;
138
- case 'n':
139
- return [self scanRestOfNull:(NSNull **)o];
140
- break;
141
- case '-':
142
- case '0'...'9':
143
- c--; // cannot verify number correctly without the first character
144
- return [self scanNumber:(NSNumber **)o];
145
- break;
146
- case '+':
147
- [self addErrorWithCode:EPARSENUM description: @"Leading + disallowed in number"];
148
- return NO;
149
- break;
150
- case 0x0:
151
- [self addErrorWithCode:EEOF description:@"Unexpected end of string"];
152
- return NO;
153
- break;
154
- default:
155
- [self addErrorWithCode:EPARSE description: @"Unrecognised leading character"];
156
- return NO;
157
- break;
158
- }
159
-
160
- NSAssert(0, @"Should never get here");
161
- return NO;
162
- }
163
-
164
- - (BOOL)scanRestOfTrue:(NSNumber **)o
165
- {
166
- if (!strncmp(c, "rue", 3)) {
167
- c += 3;
168
- *o = [NSNumber numberWithBool:YES];
169
- return YES;
170
- }
171
- [self addErrorWithCode:EPARSE description:@"Expected 'true'"];
172
- return NO;
173
- }
174
-
175
- - (BOOL)scanRestOfFalse:(NSNumber **)o
176
- {
177
- if (!strncmp(c, "alse", 4)) {
178
- c += 4;
179
- *o = [NSNumber numberWithBool:NO];
180
- return YES;
181
- }
182
- [self addErrorWithCode:EPARSE description: @"Expected 'false'"];
183
- return NO;
184
- }
185
-
186
- - (BOOL)scanRestOfNull:(NSNull **)o {
187
- if (!strncmp(c, "ull", 3)) {
188
- c += 3;
189
- *o = [NSNull null];
190
- return YES;
191
- }
192
- [self addErrorWithCode:EPARSE description: @"Expected 'null'"];
193
- return NO;
194
- }
195
-
196
- - (BOOL)scanRestOfArray:(NSMutableArray **)o {
197
- if (maxDepth && ++depth > maxDepth) {
198
- [self addErrorWithCode:EDEPTH description: @"Nested too deep"];
199
- return NO;
200
- }
201
-
202
- *o = [NSMutableArray arrayWithCapacity:8];
203
-
204
- for (; *c ;) {
205
- id v;
206
-
207
- skipWhitespace(c);
208
- if (*c == ']' && c++) {
209
- depth--;
210
- return YES;
211
- }
212
-
213
- if (![self scanValue:&v]) {
214
- [self addErrorWithCode:EPARSE description:@"Expected value while parsing array"];
215
- return NO;
216
- }
217
-
218
- [*o addObject:v];
219
-
220
- skipWhitespace(c);
221
- if (*c == ',' && c++) {
222
- skipWhitespace(c);
223
- if (*c == ']') {
224
- [self addErrorWithCode:ETRAILCOMMA description: @"Trailing comma disallowed in array"];
225
- return NO;
226
- }
227
- }
228
- }
229
-
230
- [self addErrorWithCode:EEOF description: @"End of input while parsing array"];
231
- return NO;
232
- }
233
-
234
- - (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o
235
- {
236
- if (maxDepth && ++depth > maxDepth) {
237
- [self addErrorWithCode:EDEPTH description: @"Nested too deep"];
238
- return NO;
239
- }
240
-
241
- *o = [NSMutableDictionary dictionaryWithCapacity:7];
242
-
243
- for (; *c ;) {
244
- id k, v;
245
-
246
- skipWhitespace(c);
247
- if (*c == '}' && c++) {
248
- depth--;
249
- return YES;
250
- }
251
-
252
- if (!(*c == '\"' && c++ && [self scanRestOfString:&k])) {
253
- [self addErrorWithCode:EPARSE description: @"Object key string expected"];
254
- return NO;
255
- }
256
-
257
- skipWhitespace(c);
258
- if (*c != ':') {
259
- [self addErrorWithCode:EPARSE description: @"Expected ':' separating key and value"];
260
- return NO;
261
- }
262
-
263
- c++;
264
- if (![self scanValue:&v]) {
265
- NSString *string = [NSString stringWithFormat:@"Object value expected for key: %@", k];
266
- [self addErrorWithCode:EPARSE description: string];
267
- return NO;
268
- }
269
-
270
- [*o setObject:v forKey:k];
271
-
272
- skipWhitespace(c);
273
- if (*c == ',' && c++) {
274
- skipWhitespace(c);
275
- if (*c == '}') {
276
- [self addErrorWithCode:ETRAILCOMMA description: @"Trailing comma disallowed in object"];
277
- return NO;
278
- }
279
- }
280
- }
281
-
282
- [self addErrorWithCode:EEOF description: @"End of input while parsing object"];
283
- return NO;
284
- }
285
-
286
- - (BOOL)scanRestOfString:(NSMutableString **)o
287
- {
288
- *o = [NSMutableString stringWithCapacity:16];
289
- do {
290
- // First see if there's a portion we can grab in one go.
291
- // Doing this caused a massive speedup on the long string.
292
- size_t len = strcspn(c, ctrl);
293
- if (len) {
294
- // check for
295
- id t = [[NSString alloc] initWithBytesNoCopy:(char*)c
296
- length:len
297
- encoding:NSUTF8StringEncoding
298
- freeWhenDone:NO];
299
- if (t) {
300
- [*o appendString:t];
301
- [t release];
302
- c += len;
303
- }
304
- }
305
-
306
- if (*c == '"') {
307
- c++;
308
- return YES;
309
-
310
- } else if (*c == '\\') {
311
- unichar uc = *++c;
312
- switch (uc) {
313
- case '\\':
314
- case '/':
315
- case '"':
316
- break;
317
-
318
- case 'b': uc = '\b'; break;
319
- case 'n': uc = '\n'; break;
320
- case 'r': uc = '\r'; break;
321
- case 't': uc = '\t'; break;
322
- case 'f': uc = '\f'; break;
323
-
324
- case 'u':
325
- c++;
326
- if (![self scanUnicodeChar:&uc]) {
327
- [self addErrorWithCode:EUNICODE description: @"Broken unicode character"];
328
- return NO;
329
- }
330
- c--; // hack.
331
- break;
332
- default:
333
- [self addErrorWithCode:EESCAPE description: [NSString stringWithFormat:@"Illegal escape sequence '0x%x'", uc]];
334
- return NO;
335
- break;
336
- }
337
- CFStringAppendCharacters((CFMutableStringRef)*o, &uc, 1);
338
- c++;
339
-
340
- } else if (*c < 0x20) {
341
- [self addErrorWithCode:ECTRL description: [NSString stringWithFormat:@"Unescaped control character '0x%x'", *c]];
342
- return NO;
343
-
344
- } else {
345
- NSLog(@"should not be able to get here");
346
- }
347
- } while (*c);
348
-
349
- [self addErrorWithCode:EEOF description:@"Unexpected EOF while parsing string"];
350
- return NO;
351
- }
352
-
353
- - (BOOL)scanUnicodeChar:(unichar *)x
354
- {
355
- unichar hi, lo;
356
-
357
- if (![self scanHexQuad:&hi]) {
358
- [self addErrorWithCode:EUNICODE description: @"Missing hex quad"];
359
- return NO;
360
- }
361
-
362
- if (hi >= 0xd800) { // high surrogate char?
363
- if (hi < 0xdc00) { // yes - expect a low char
364
-
365
- if (!(*c == '\\' && ++c && *c == 'u' && ++c && [self scanHexQuad:&lo])) {
366
- [self addErrorWithCode:EUNICODE description: @"Missing low character in surrogate pair"];
367
- return NO;
368
- }
369
-
370
- if (lo < 0xdc00 || lo >= 0xdfff) {
371
- [self addErrorWithCode:EUNICODE description:@"Invalid low surrogate char"];
372
- return NO;
373
- }
374
-
375
- hi = (hi - 0xd800) * 0x400 + (lo - 0xdc00) + 0x10000;
376
-
377
- } else if (hi < 0xe000) {
378
- [self addErrorWithCode:EUNICODE description:@"Invalid high character in surrogate pair"];
379
- return NO;
380
- }
381
- }
382
-
383
- *x = hi;
384
- return YES;
385
- }
386
-
387
- - (BOOL)scanHexQuad:(unichar *)x
388
- {
389
- *x = 0;
390
- for (int i = 0; i < 4; i++) {
391
- unichar uc = *c;
392
- c++;
393
- int d = (uc >= '0' && uc <= '9')
394
- ? uc - '0' : (uc >= 'a' && uc <= 'f')
395
- ? (uc - 'a' + 10) : (uc >= 'A' && uc <= 'F')
396
- ? (uc - 'A' + 10) : -1;
397
- if (d == -1) {
398
- [self addErrorWithCode:EUNICODE description:@"Missing hex digit in quad"];
399
- return NO;
400
- }
401
- *x *= 16;
402
- *x += d;
403
- }
404
- return YES;
405
- }
406
-
407
- - (BOOL)scanNumber:(NSNumber **)o
408
- {
409
- const char *ns = c;
410
-
411
- // The logic to test for validity of the number formatting is relicensed
412
- // from JSON::XS with permission from its author Marc Lehmann.
413
- // (Available at the CPAN: http://search.cpan.org/dist/JSON-XS/ .)
414
-
415
- if ('-' == *c)
416
- c++;
417
-
418
- if ('0' == *c && c++) {
419
- if (isdigit(*c)) {
420
- [self addErrorWithCode:EPARSENUM description: @"Leading 0 disallowed in number"];
421
- return NO;
422
- }
423
-
424
- } else if (!isdigit(*c) && c != ns) {
425
- [self addErrorWithCode:EPARSENUM description: @"No digits after initial minus"];
426
- return NO;
427
-
428
- } else {
429
- skipDigits(c);
430
- }
431
-
432
- // Fractional part
433
- if ('.' == *c && c++) {
434
-
435
- if (!isdigit(*c)) {
436
- [self addErrorWithCode:EPARSENUM description: @"No digits after decimal point"];
437
- return NO;
438
- }
439
- skipDigits(c);
440
- }
441
-
442
- // Exponential part
443
- if ('e' == *c || 'E' == *c) {
444
- c++;
445
-
446
- if ('-' == *c || '+' == *c)
447
- c++;
448
-
449
- if (!isdigit(*c)) {
450
- [self addErrorWithCode:EPARSENUM description: @"No digits after exponent"];
451
- return NO;
452
- }
453
- skipDigits(c);
454
- }
455
-
456
- id str = [[NSString alloc] initWithBytesNoCopy:(char*)ns
457
- length:c - ns
458
- encoding:NSUTF8StringEncoding
459
- freeWhenDone:NO];
460
- [str autorelease];
461
- if (str && (*o = [NSDecimalNumber decimalNumberWithString:str]))
462
- return YES;
463
-
464
- [self addErrorWithCode:EPARSENUM description: @"Failed creating decimal instance"];
465
- return NO;
466
- }
467
-
468
- - (BOOL)scanIsAtEnd
469
- {
470
- skipWhitespace(c);
471
- return !*c;
472
- }
473
-
474
-
475
- @end