~ubuntu-branches/ubuntu/trusty/gnustep-base/trusty

« back to all changes in this revision

Viewing changes to Source/NSXMLNode.m

  • Committer: Package Import Robot
  • Author(s): Benjamin Drung
  • Date: 2012-11-21 13:56:22 UTC
  • mfrom: (8.1.5 experimental)
  • Revision ID: package-import@ubuntu.com-20121121135622-1w035dpxneardw8q
Tags: 1.24.0-1ubuntu1
Backport upstream fix for recent libxml2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
   modify it under the terms of the GNU Lesser General Public
11
11
   License as published by the Free Software Foundation; either
12
12
   version 3 of the License, or (at your option) any later version.
13
 
   
 
13
 
14
14
   This library is distributed in the hope that it will be useful,
15
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24
24
 
25
25
#import "common.h"
26
26
 
 
27
#define GSInternal              NSXMLNodeInternal
27
28
#import "NSXMLPrivate.h"
 
29
#import "GSInternal.h"
 
30
GS_PRIVATE_INTERNAL(NSXMLNode)
 
31
 
28
32
 
29
33
@implementation NSXMLNode
30
34
 
35
39
 
36
40
  n = [[[self alloc] initWithKind: NSXMLAttributeKind] autorelease];
37
41
  [n setStringValue: stringValue];
 
42
  [n setName: name];
38
43
  return n;
39
44
}
40
45
 
47
52
  n = [[[self alloc] initWithKind: NSXMLAttributeKind] autorelease];
48
53
  [n setURI: URI];
49
54
  [n setStringValue: stringValue];
 
55
  [n setName: name];
50
56
  return n;
51
57
}
52
58
 
119
125
  NSXMLElement  *e;
120
126
  NSXMLNode     *t;
121
127
 
122
 
  e = [self elementWithName: name]; 
 
128
  e = [self elementWithName: name];
123
129
  t = [[self alloc] initWithKind: NSXMLTextKind];
124
130
  [t setStringValue: string];
125
131
  [e addChild: t];
178
184
 
179
185
- (NSXMLNode*) childAtIndex: (NSUInteger)index
180
186
{
181
 
  return [self notImplemented: _cmd];   // FIXME ... fetch from libxml
 
187
  return [internal->children objectAtIndex: index];
182
188
}
183
189
 
184
190
- (NSUInteger) childCount
185
191
{
186
 
  [self notImplemented: _cmd];  // FIXME ... fetch from libxml
187
 
  return 0;
 
192
  return internal->childCount;
188
193
}
189
194
 
190
 
- (NSArray*)children
 
195
- (NSArray*) children
191
196
{
192
 
  return [self notImplemented: _cmd];   // FIXME ... fetch from libxml
 
197
  return internal->children;
193
198
}
194
199
 
195
200
- (id) copyWithZone: (NSZone*)zone
196
201
{
197
 
  [self notImplemented: _cmd];
198
 
  return nil;
 
202
  id c = [[self class] allocWithZone: zone];
 
203
 
 
204
  c = [c initWithKind: internal->kind options: internal->options];
 
205
  [c setName: [self name]];
 
206
  [c setURI: [self URI]];
 
207
  [c setObjectValue: [self objectValue]];
 
208
  [c setStringValue: [self stringValue]];
 
209
 
 
210
  return c;
199
211
}
200
212
 
201
213
- (void) dealloc
202
214
{
203
 
  [self detach];
204
 
  [_objectValue release];
 
215
  if (GS_EXISTS_INTERNAL)
 
216
    {
 
217
      [self detach];
 
218
      [internal->name release];
 
219
      [internal->URI release];
 
220
      [internal->children release];
 
221
      [internal->objectValue release];
 
222
      [internal->stringValue release];
 
223
      GS_DESTROY_INTERNAL(NSXMLNode);
 
224
    }
205
225
  [super dealloc];
206
226
}
207
227
 
208
228
- (void) detach
209
229
{
210
 
  if (_parent != nil)
211
 
    {
212
 
      [self notImplemented: _cmd];      // FIXME ... remove from libxml
213
 
    }
 
230
  [(NSXMLElement*)internal->parent removeChildAtIndex: [self index]];
 
231
}
 
232
 
 
233
- (NSUInteger) hash
 
234
{
 
235
  return [internal->name hash];
214
236
}
215
237
 
216
238
- (NSUInteger) index
217
239
{
218
 
  return _index;
 
240
  if (nil == internal->parent)
 
241
    {
 
242
      return 0;
 
243
    }
 
244
  return [GSIVar(internal->parent, children) indexOfObjectIdenticalTo: self];
 
245
}
 
246
 
 
247
- (id) init
 
248
{
 
249
  return [self initWithKind: NSXMLInvalidKind];
219
250
}
220
251
 
221
252
- (id) initWithKind:(NSXMLNodeKind) kind
224
255
  return self;
225
256
}
226
257
 
227
 
- (id) initWithKind: (NSXMLNodeKind)kind options: (NSUInteger)options
 
258
- (id) initWithKind: (NSXMLNodeKind)kind options: (NSUInteger)theOptions
228
259
{
229
 
  if ((self = [super init]) != nil)
230
 
    {
231
 
      [self notImplemented: _cmd];      // FIXME ... use libxml
232
 
    }
 
260
  Class theSubclass = [NSXMLNode class];
 
261
 
 
262
GSOnceMLog(@"WARNING  the XML DOM classes are not currently implemented to a usable level, but we expect to have an implementation based on libxml2 in place for the next release.");
 
263
  if (nil == (self = [super init]))
 
264
    {
 
265
      return nil;
 
266
    }
 
267
 
 
268
  /*
 
269
   * We find the correct subclass for specific node kinds:
 
270
   */
 
271
  switch (kind)
 
272
    {
 
273
      case NSXMLDocumentKind:
 
274
        theSubclass = [NSXMLDocument class];
 
275
        break;
 
276
 
 
277
      case NSXMLElementKind:
 
278
        theSubclass = [NSXMLElement class];
 
279
        break;
 
280
 
 
281
      case NSXMLDTDKind:
 
282
        theSubclass = [NSXMLDTD class];
 
283
        break;
 
284
 
 
285
      case NSXMLEntityDeclarationKind:
 
286
      case NSXMLElementDeclarationKind:
 
287
      case NSXMLNotationDeclarationKind:
 
288
        theSubclass = [NSXMLDTDNode class];
 
289
        break;
 
290
 
 
291
      default:
 
292
        break;
 
293
    }
 
294
 
 
295
  /*
 
296
   * Check whether we are already initializing an instance of the given
 
297
   * subclass. If we are not, release ourselves and allocate a subclass instance
 
298
   * instead.
 
299
   */
 
300
  if (NO == [self isKindOfClass: theSubclass])
 
301
    {
 
302
      [self release];
 
303
      return [[theSubclass alloc] initWithKind: kind
 
304
                                       options: theOptions];
 
305
    }
 
306
 
 
307
  /* Create holder for internal instance variables if needed.
 
308
   */
 
309
  GS_CREATE_INTERNAL(NSXMLNode)
 
310
 
 
311
  /* If we are initializing for the correct class, we can actually perform
 
312
   * initializations:
 
313
   */
 
314
  internal->kind = kind;
 
315
  internal->options = theOptions;
 
316
  internal->stringValue = @"";
233
317
  return self;
234
318
}
235
319
 
 
320
- (BOOL) isEqual: (id)other
 
321
{
 
322
  NSString      *s;
 
323
  NSArray       *c;
 
324
 
 
325
  if (other == (id)self)
 
326
    {
 
327
      return YES;
 
328
    }
 
329
 
 
330
  if (NO == [other isKindOfClass: [self class]])
 
331
    {
 
332
      return NO;
 
333
    }
 
334
 
 
335
  if ([(NSXMLNode*)other kind] != internal->kind)
 
336
    {
 
337
      return NO;
 
338
    }
 
339
 
 
340
  s = [other name];
 
341
  if (s != internal->name && NO == [s isEqual: internal->name])
 
342
    {
 
343
      return NO;
 
344
    }
 
345
 
 
346
  s = [other URI];
 
347
  if (s != internal->URI && NO == [s isEqual: internal->URI])
 
348
    {
 
349
      return NO;
 
350
    }
 
351
 
 
352
  c = [other children];
 
353
  if (c != internal->children && NO == [c isEqual: internal->children])
 
354
    {
 
355
      return NO;
 
356
    }
 
357
 
 
358
  return YES;
 
359
}
 
360
 
236
361
- (NSXMLNodeKind) kind
237
362
{
238
 
  return _kind;
 
363
  return internal->kind;
239
364
}
240
365
 
241
366
- (NSUInteger) level
242
367
{
243
368
  NSUInteger    level = 0;
244
 
  NSXMLNode     *tmp = _parent;
 
369
  NSXMLNode     *tmp = internal->parent;
245
370
 
246
371
  while (tmp != nil)
247
372
    {
248
373
      level++;
249
 
      tmp = tmp->_parent;
 
374
      tmp = GSIVar(tmp, parent);
250
375
    }
251
376
  return level;
252
377
}
258
383
 
259
384
- (NSString*) name
260
385
{
261
 
  return [self notImplemented: _cmd];   // FIXME ... fetch from libxml
 
386
  return internal->name; 
 
387
}
 
388
 
 
389
- (NSXMLNode*) _nodeFollowingInNaturalDirection: (BOOL)forward
 
390
{
 
391
  NSXMLNode *ancestor = internal->parent;
 
392
  NSXMLNode *candidate = nil;
 
393
 
 
394
  /* Node walking is a depth-first thingy. Hence, we consider children first: */
 
395
  if (0 != internal->childCount)
 
396
    {
 
397
      NSUInteger theIndex = 0;
 
398
      if (NO == forward)
 
399
        {
 
400
          theIndex = (internal->childCount) - 1;
 
401
        }
 
402
      candidate = [internal->children objectAtIndex: theIndex];
 
403
    }
 
404
 
 
405
  /* If there are no children, we move on to siblings: */
 
406
  if (nil == candidate)
 
407
    {
 
408
      if (forward)
 
409
        {
 
410
          candidate = internal->nextSibling;
 
411
        }
 
412
      else
 
413
        {
 
414
          candidate = internal->previousSibling;
 
415
        }
 
416
    }
 
417
 
 
418
  /* If there are no siblings left for the receiver, we recurse down to the root
 
419
   * of the tree until we find an ancestor with further siblings: */
 
420
  while ((nil == candidate) && (nil != ancestor))
 
421
    {
 
422
      if (forward)
 
423
        {
 
424
          candidate = [ancestor nextSibling];
 
425
        }
 
426
      else
 
427
        {
 
428
          candidate = [ancestor previousSibling];
 
429
        }
 
430
      ancestor = GSIVar(ancestor, parent);
 
431
    }
 
432
 
 
433
  /* No children, no next siblings, no next siblings for any ancestor: We are
 
434
   * the last node */
 
435
  if (nil == candidate)
 
436
    {
 
437
      return nil;
 
438
    }
 
439
 
 
440
  /* Sanity check: Namespace and attribute nodes are skipped: */
 
441
  if ((NSXMLAttributeKind == GSIVar(candidate, kind))
 
442
    || (NSXMLNamespaceKind == GSIVar(candidate, kind)))
 
443
    {
 
444
      return [candidate _nodeFollowingInNaturalDirection: forward];
 
445
    }
 
446
  return candidate;
262
447
}
263
448
 
264
449
- (NSXMLNode*) nextNode
265
450
{
266
 
  return [self notImplemented: _cmd];   // FIXME ... fetch from libxml
 
451
  return [self _nodeFollowingInNaturalDirection: YES];
267
452
}
268
453
 
269
454
- (NSXMLNode*) nextSibling
270
455
{
271
 
  return [self notImplemented: _cmd];   // FIXME ... fetch from libxml
 
456
  return internal->nextSibling;
272
457
}
273
458
 
274
459
- (id) objectValue
275
460
{
276
 
  return _objectValue;
 
461
  return internal->objectValue;
277
462
}
278
463
 
279
464
- (NSXMLNode*) parent
280
465
{
281
 
  return _parent;
 
466
  return internal->parent;
282
467
}
283
468
 
284
469
- (NSString*) prefix
288
473
 
289
474
- (NSXMLNode*) previousNode
290
475
{
291
 
  return [self notImplemented: _cmd];   // FIXME ... fetch from libxml
 
476
  return [self _nodeFollowingInNaturalDirection: NO];
292
477
}
293
478
 
294
479
- (NSXMLNode*) previousSibling
295
480
{
296
 
  return [self notImplemented: _cmd];   // FIXME ... fetch from libxml
 
481
  return internal->previousSibling;
 
482
 
297
483
}
298
484
 
299
485
- (NSXMLDocument*) rootDocument
300
486
{
301
 
  return [self notImplemented: _cmd];   // FIXME ... fetch from libxml
 
487
  NSXMLNode *ancestor = internal->parent;
 
488
  /*
 
489
   * Short-circuit evaluation gurantees that the nil-pointer is not
 
490
   * dereferenced:
 
491
   */
 
492
  while ((ancestor != nil)
 
493
    && (NSXMLDocumentKind != GSIVar(ancestor, kind)))
 
494
    {
 
495
      ancestor = GSIVar(ancestor, parent);
 
496
    }
 
497
  return (NSXMLDocument*)ancestor;
302
498
}
303
499
 
304
500
- (NSString*) stringValue
305
501
{
306
 
  // FIXME
307
 
  return _objectValue;
 
502
  return internal->stringValue;
308
503
}
309
504
 
310
505
- (NSString*) URI
311
506
{
312
 
  return [self notImplemented: _cmd];   // FIXME ... fetch from libxml
 
507
  return internal->URI; // FIXME ... fetch from libxml
313
508
}
314
509
 
315
510
- (NSString*) XMLString
319
514
 
320
515
- (NSString*) XMLStringWithOptions: (NSUInteger)options
321
516
{
322
 
  return [self notImplemented: _cmd];   // FIXME ... generate from libxml
 
517
  NSMutableString *returnValue = [NSMutableString string];
 
518
  NSXMLNodeKind kind = [self kind];
 
519
 
 
520
  if (kind == NSXMLAttributeKind)
 
521
    {
 
522
      [returnValue appendString: [self name]];
 
523
      [returnValue appendString: @"=\""];
 
524
      [returnValue appendString: [self stringValue]];
 
525
      [returnValue appendString: @"\""];
 
526
    }
 
527
  else
 
528
    {
 
529
      // for all other types, do nothing for now...
 
530
    }
 
531
 
 
532
  return returnValue;
323
533
}
324
534
 
325
535
- (void) setObjectValue: (id)value
326
536
{
327
 
  ASSIGN(_objectValue, value);
 
537
  ASSIGN(internal->objectValue, value);
328
538
}
329
539
 
330
 
- (void) setName: (NSString*)name
 
540
- (void) setName: (NSString *)name
331
541
{
332
 
  [self notImplemented: _cmd];  // FIXME ... set in libxml
 
542
  if (NSXMLInvalidKind != internal->kind)
 
543
    {
 
544
      ASSIGNCOPY(internal->name, name);
 
545
    }
333
546
}
334
547
 
335
548
- (void) setStringValue: (NSString*)string
339
552
 
340
553
- (void) setURI: (NSString*)URI
341
554
{
342
 
  [self notImplemented: _cmd];  // FIXME ... set in libxml
 
555
  if (NSXMLInvalidKind != internal->kind)
 
556
    {
 
557
      ASSIGNCOPY(internal->URI, URI);
 
558
    }
343
559
}
344
560
 
345
561
- (void) setStringValue: (NSString*)string resolvingEntities: (BOOL)resolve
346
562
{
347
 
  [self notImplemented: _cmd];  // FIXME ... set in libxml
 
563
  if (resolve == NO)
 
564
    {
 
565
      ASSIGNCOPY(internal->stringValue, string);
 
566
    }
 
567
  else
 
568
    {
 
569
      // need to actually resolve entities...
 
570
      ASSIGNCOPY(internal->stringValue, string);
 
571
    }
 
572
  if (nil == internal->stringValue)
 
573
    {
 
574
      internal->stringValue = @"";      // string value may not be nil
 
575
    }
348
576
}
349
577
 
350
578
- (NSString*) XPath