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

« back to all changes in this revision

Viewing changes to Source/GSDictionary.m

Tags: upstream-1.20.0
ImportĀ upstreamĀ versionĀ 1.20.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
   */
24
24
 
25
25
 
26
 
#import "config.h"
 
26
#import "common.h"
27
27
#import "Foundation/NSDictionary.h"
28
28
#import "Foundation/NSEnumerator.h"
29
29
#import "Foundation/NSAutoreleasePool.h"
30
 
#import "Foundation/NSString.h"
31
30
#import "Foundation/NSException.h"
32
31
#import "Foundation/NSPortCoder.h"
33
 
#import "Foundation/NSDebug.h"
34
32
// For private method _decodeArrayOfObjectsForKey:
35
33
#import "Foundation/NSKeyedArchiver.h"
36
34
 
47
45
#define GSI_MAP_RETAIN_KEY(M, X)        ((X).obj) = \
48
46
                                [((id)(X).obj) copyWithZone: map->zone]
49
47
 
 
48
#if     GS_WITH_GC
 
49
#include        <gc_typed.h>
 
50
static GC_descr nodeDesc;       // Type descriptor for map node.
 
51
#define GSI_MAP_NODES(M, X) \
 
52
(GSIMapNode)GC_calloc_explicitly_typed(X, sizeof(GSIMapNode_t), nodeDesc)
 
53
#endif
 
54
 
50
55
#include        "GNUstepBase/GSIMap.h"
51
56
 
52
57
@interface GSDictionary : NSDictionary
60
65
{
61
66
@public
62
67
  GSIMapTable_t map;
 
68
  NSUInteger _version;
63
69
}
64
70
@end
65
71
 
82
88
{
83
89
  if (self == [GSDictionary class])
84
90
    {
 
91
#if     GS_WITH_GC
 
92
      /* We create a typed memory descriptor for map nodes.
 
93
       * The pointers to the key and value need to be scanned.
 
94
       */
 
95
      GC_word   w[GC_BITMAP_SIZE(GSIMapNode_t)] = {0};
 
96
      GC_set_bit(w, GC_WORD_OFFSET(GSIMapNode_t, key));
 
97
      GC_set_bit(w, GC_WORD_OFFSET(GSIMapNode_t, value));
 
98
      nodeDesc = GC_make_descriptor(w, GC_WORD_LEN(GSIMapNode_t));
 
99
#endif
85
100
      nxtSel = @selector(nextObject);
86
101
      objSel = @selector(objectForKey:);
87
102
    }
92
107
  return RETAIN(self);
93
108
}
94
109
 
95
 
- (unsigned) count
 
110
- (NSUInteger) count
96
111
{
97
112
  return map.nodeCount;
98
113
}
111
126
    }
112
127
  else
113
128
    {
114
 
      unsigned          count = map.nodeCount;
 
129
      unsigned  count = map.nodeCount;
115
130
      SEL               sel = @selector(encodeObject:);
116
131
      IMP               imp = [aCoder methodForSelector: sel];
117
132
      GSIMapEnumerator_t        enumerator = GSIMapEnumeratorForMap(&map);
128
143
    }
129
144
}
130
145
 
131
 
- (unsigned) hash
 
146
- (NSUInteger) hash
132
147
{
133
148
  return map.nodeCount;
134
149
}
156
171
      [aCoder decodeValueOfObjCType: @encode(unsigned)
157
172
                                 at: &count];
158
173
 
159
 
      GSIMapInitWithZoneAndCapacity(&map, GSObjCZone(self), count);
 
174
      GSIMapInitWithZoneAndCapacity(&map, [self zone], count);
160
175
      while (count-- > 0)
161
176
        {
162
177
          (*imp)(aCoder, sel, type, &key);
168
183
}
169
184
 
170
185
/* Designated initialiser */
171
 
- (id) initWithObjects: (id*)objs forKeys: (id*)keys count: (unsigned)c
 
186
- (id) initWithObjects: (id*)objs forKeys: (id*)keys count: (NSUInteger)c
172
187
{
173
 
  unsigned int  i;
 
188
  NSUInteger    i;
174
189
 
175
 
  GSIMapInitWithZoneAndCapacity(&map, GSObjCZone(self), c);
 
190
  GSIMapInitWithZoneAndCapacity(&map, [self zone], c);
176
191
  for (i = 0; i < c; i++)
177
192
    {
178
193
      GSIMapNode        node;
179
194
 
180
195
      if (keys[i] == nil)
181
196
        {
182
 
          IF_NO_GC(AUTORELEASE(self));
 
197
          DESTROY(self);
183
198
          [NSException raise: NSInvalidArgumentException
184
199
                      format: @"Tried to init dictionary with nil key"];
185
200
        }
186
201
      if (objs[i] == nil)
187
202
        {
188
 
          IF_NO_GC(AUTORELEASE(self));
 
203
          DESTROY(self);
189
204
          [NSException raise: NSInvalidArgumentException
190
205
                      format: @"Tried to init dictionary with nil value"];
191
206
        }
211
226
- (id) initWithDictionary: (NSDictionary*)other
212
227
                copyItems: (BOOL)shouldCopy
213
228
{
214
 
  NSZone        *z = GSObjCZone(self);
215
 
  unsigned      c = [other count];
 
229
  NSZone        *z = [self zone];
 
230
  NSUInteger    c = [other count];
216
231
 
217
232
  GSIMapInitWithZoneAndCapacity(&map, z, c);
218
 
 
219
233
  if (c > 0)
220
234
    {
221
235
      NSEnumerator      *e = [other keyEnumerator];
222
236
      IMP               nxtObj = [e methodForSelector: nxtSel];
223
237
      IMP               otherObj = [other methodForSelector: objSel];
224
238
      BOOL              isProxy = [other isProxy];
225
 
      unsigned          i;
 
239
      NSUInteger        i;
226
240
 
227
241
      for (i = 0; i < c; i++)
228
242
        {
243
257
          k = [k copyWithZone: z];
244
258
          if (k == nil)
245
259
            {
246
 
              IF_NO_GC(AUTORELEASE(self));
 
260
              DESTROY(self);
247
261
              [NSException raise: NSInvalidArgumentException
248
262
                          format: @"Tried to init dictionary with nil key"];
249
263
            }
257
271
            }
258
272
          if (o == nil)
259
273
            {
260
 
              IF_NO_GC(AUTORELEASE(self));
 
274
              DESTROY(self);
261
275
              [NSException raise: NSInvalidArgumentException
262
276
                          format: @"Tried to init dictionary with nil value"];
263
277
            }
279
293
 
280
294
- (BOOL) isEqualToDictionary: (NSDictionary*)other
281
295
{
282
 
  unsigned      count;
 
296
  NSUInteger    count;
283
297
 
284
298
  if (other == self)
285
299
    {
339
353
  return nil;
340
354
}
341
355
 
 
356
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state      
 
357
                                   objects: (id*)stackbuf
 
358
                                     count: (NSUInteger)len
 
359
{
 
360
  state->mutationsPtr = (unsigned long *)self;
 
361
  return GSIMapCountByEnumeratingWithStateObjectsCount
 
362
    (&map, state, stackbuf, len);
 
363
}
342
364
@end
343
365
 
344
366
@implementation GSMutableDictionary
364
386
}
365
387
 
366
388
/* Designated initialiser */
367
 
- (id) initWithCapacity: (unsigned)cap
 
389
- (id) initWithCapacity: (NSUInteger)cap
368
390
{
369
 
  GSIMapInitWithZoneAndCapacity(&map, GSObjCZone(self), cap);
 
391
  GSIMapInitWithZoneAndCapacity(&map, [self zone], cap);
370
392
  return self;
371
393
}
372
394
 
386
408
{
387
409
  GSIMapNode    node;
388
410
 
 
411
  _version++;
389
412
  if (aKey == nil)
390
413
    {
391
414
      NSException       *e;
418
441
    {
419
442
      GSIMapAddPair(&map, (GSIMapKey)aKey, (GSIMapVal)anObject);
420
443
    }
 
444
  _version++;
421
445
}
422
446
 
423
447
- (void) removeAllObjects
424
448
{
 
449
  _version++;
425
450
  GSIMapCleanMap(&map);
 
451
  _version++;
426
452
}
427
453
 
428
454
- (void) removeObjectForKey: (id)aKey
432
458
      NSWarnMLog(@"attempt to remove nil key from dictionary %@", self);
433
459
      return;
434
460
    }
 
461
  _version++;
435
462
  GSIMapRemoveKey(&map, (GSIMapKey)aKey);
 
463
  _version++;
436
464
}
437
465
 
 
466
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state      
 
467
                                   objects: (id*)stackbuf
 
468
                                     count: (NSUInteger)len
 
469
{
 
470
  state->mutationsPtr = (unsigned long *)&_version;
 
471
  return GSIMapCountByEnumeratingWithStateObjectsCount
 
472
    (&map, state, stackbuf, len);
 
473
}
438
474
@end
439
475
 
440
476
@implementation GSDictionaryKeyEnumerator
490
526
- (id) initWithCoder: (NSCoder*)aCoder
491
527
{
492
528
  NSLog(@"Warning - decoding archive containing obsolete %@ object - please delete/replace this archive", NSStringFromClass([self class]));
493
 
  RELEASE(self);
 
529
  DESTROY(self);
494
530
  self = (id)NSAllocateObject([GSDictionary class], 0, NSDefaultMallocZone());
495
531
  self = [self initWithCoder: aCoder];
496
532
  return self;
503
539
- (id) initWithCoder: (NSCoder*)aCoder
504
540
{
505
541
  NSLog(@"Warning - decoding archive containing obsolete %@ object - please delete/replace this archive", NSStringFromClass([self class]));
506
 
  RELEASE(self);
 
542
  DESTROY(self);
507
543
  self = (id)NSAllocateObject([GSMutableDictionary class], 0, NSDefaultMallocZone());
508
544
  self = [self initWithCoder: aCoder];
509
545
  return self;