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

« back to all changes in this revision

Viewing changes to Source/GSString.m

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
   Boston, MA 02111 USA.
34
34
*/
35
35
 
36
 
#import "config.h"
37
 
#import "GNUstepBase/preface.h"
38
 
#import "Foundation/NSString.h"
 
36
#import "common.h"
39
37
#import "Foundation/NSCoder.h"
40
38
#import "Foundation/NSArray.h"
41
39
#import "Foundation/NSData.h"
44
42
#import "Foundation/NSRange.h"
45
43
#import "Foundation/NSException.h"
46
44
#import "Foundation/NSValue.h"
47
 
#import "Foundation/NSDebug.h"
48
 
#import "Foundation/NSObjCRuntime.h"
49
45
#import "Foundation/NSKeyedArchiver.h"
50
46
#import "GNUstepBase/GSObjCRuntime.h"
51
 
#include <limits.h>
 
47
#import "GNUstepBase/NSObject+GNUstepBase.h"
52
48
 
53
49
#import "GSPrivate.h"
54
50
 
 
51
#ifdef HAVE_MALLOC_H
 
52
#include <malloc.h>
 
53
#endif
 
54
#ifdef HAVE_ALLOCA_H
 
55
#include <alloca.h>
 
56
#endif
 
57
 
55
58
/* memcpy(), strlen(), strcmp() are gcc builtin's */
56
59
 
57
60
#import "GNUstepBase/Unicode.h"
94
97
_contents buffer is guaranteed to remain valid at least until the instance
95
98
has been deallocated.
96
99
 
97
 
(It really should be named 'ownsContents' or something similar, but it's
98
 
'free' in GSMutableString, and the structures need to be interchangeable.)
99
 
 
100
100
Many optimizations, such as retaining instead of copying, and using pointers
101
101
to another strings _contents buffer, are valid only if this flag is set.
102
102
 
125
125
 
126
126
GS*BufferString, concrete subclasses that store the data in an external
127
127
(wrt. the instance itself) buffer. The buffer may or may not be owned
128
 
by the instance; the 'free' flag indicates which. If it is set,
129
 
we need to free the buffer when we are deallocated.
 
128
by the instance; the 'owned' flag indicates which. If it is set,
 
129
we may need to free the buffer when we are deallocated.
130
130
*/
131
131
@interface GSCBufferString : GSCString
132
132
{
172
172
}
173
173
@end
174
174
 
175
 
typedef struct {
176
 
  @defs(GSCSubString)
177
 
} GSSubstringStruct;
178
 
 
179
175
/*
180
176
 *      Include sequence handling code with instructions to generate search
181
177
 *      and compare functions for NSString objects.
216
212
#define GSEQ_S  GSEQ_CS
217
213
#include "GSeq.h"
218
214
 
219
 
/*
220
 
 *      Include sequence handling code with instructions to generate search
221
 
 *      and compare functions for NSString objects.
222
 
 */
223
 
#define GSEQ_STRCOMP    strCompNsNs
224
215
#define GSEQ_STRRANGE   strRangeNsNs
225
216
#define GSEQ_O  GSEQ_NS
226
217
#define GSEQ_S  GSEQ_NS
310
301
        [NSStringClass instanceMethodForSelector: equalSel];
311
302
      hashSel = @selector(hash);
312
303
      hashImp = (unsigned (*)(id, SEL))
313
 
        [NSStringClass instanceMethodForSelector: hashSel];
 
304
        [GSStringClass instanceMethodForSelector: hashSel];
314
305
 
315
306
      caiSel = @selector(characterAtIndex:);
316
307
      gcrSel = @selector(getCharacters:range:);
343
334
  return self;          // placeholders never get released.
344
335
}
345
336
 
346
 
- (unichar) characterAtIndex: (unsigned)index
 
337
- (unichar) characterAtIndex: (NSUInteger)index
347
338
{
348
339
  [NSException raise: NSInternalInconsistencyException
349
340
              format: @"attempt to use uninitialised string"];
352
343
 
353
344
- (void) dealloc
354
345
{
 
346
  NSLog(@"Warning ... attempt to deallocate instance of %@ in zone %p",
 
347
    NSStringFromClass([self class]), [self zone]);
355
348
  GSNOSUPERDEALLOC;     // Placeholders never get deallocated.
356
349
}
357
350
 
367
360
 * Remove any BOM and perform byte swapping if required.
368
361
 */
369
362
static void
370
 
fixBOM(unsigned char **bytes, unsigned *length, BOOL *shouldFree,
 
363
fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *owned,
371
364
  NSStringEncoding encoding)
372
365
{
373
366
  unsigned char *b = *bytes;
379
372
      // Got a byte order marker ... remove it.
380
373
      if (len == sizeof(unichar))
381
374
        {
382
 
          if (*shouldFree)
 
375
          if (*owned)
383
376
            {
384
377
              NSZoneFree(NSZoneFromPointer(b), b);
 
378
              *owned = NO;
385
379
            }
386
380
          *length = 0;
387
 
          *shouldFree = NO;
388
381
          *bytes = 0;
389
382
        }
390
383
      else
391
384
        {
392
 
          NSZone        *z = NSZoneFromPointer(b);
393
385
          unsigned char *from = b;
394
386
          unsigned char *to;
395
387
          unichar       u;
398
390
          len -= sizeof(unichar);
399
391
          memcpy(&u, from, sizeof(unichar));
400
392
          from += sizeof(unichar);
401
 
          to = NSZoneMalloc(z, len);
 
393
#if     GS_WITH_GC
 
394
          to = NSAllocateCollectable(len, 0);
 
395
#else
 
396
          to = NSZoneMalloc(NSDefaultMallocZone(), len);
 
397
#endif
402
398
          if (u == 0xFEFF)
403
399
            {
404
400
              // Native byte order
414
410
                  to[i+1] = from[i];
415
411
                }
416
412
            }
417
 
          if (*shouldFree == YES)
418
 
            {
419
 
              NSZoneFree(z, b);
 
413
          if (*owned == YES)
 
414
            {
 
415
              NSZoneFree(NSZoneFromPointer(b), b);
 
416
            }
 
417
          else
 
418
            {
 
419
              *owned = YES;
420
420
            }
421
421
          *length = len;
422
422
          *bytes = to;
423
 
          *shouldFree = YES;
424
423
        }
425
424
    }
426
425
  else if (encoding == NSUTF8StringEncoding && len >= 3
428
427
    {
429
428
      if (len == 3)
430
429
        {
431
 
          if (*shouldFree)
 
430
          if (*owned)
432
431
            {
433
432
              NSZoneFree(NSZoneFromPointer(b), b);
 
433
              *owned = NO;
434
434
            }
435
435
          *length = 0;
436
 
          *shouldFree = NO;
437
436
          *bytes = 0;
438
437
        }
439
438
      else
440
439
        {
441
 
          NSZone        *z = NSZoneFromPointer(b);
442
440
          unsigned char *from = b;
443
441
          unsigned char *to;
444
442
 
445
443
          // Got a byte order marker ... remove it.
446
444
          len -= 3;
447
445
          from += 3;
448
 
          to = NSZoneMalloc(z, len);
 
446
#if     GS_WITH_GC
 
447
          to = NSAllocateCollectable(len, 0);
 
448
#else
 
449
          to = NSZoneMalloc(NSDefaultMallocZone(), len);
 
450
#endif
449
451
          memcpy(to, from, len);
450
 
          if (*shouldFree == YES)
451
 
            {
452
 
              NSZoneFree(z, b);
 
452
          if (*owned == YES)
 
453
            {
 
454
              NSZoneFree(NSZoneFromPointer(b), b);
 
455
            }
 
456
          else
 
457
            {
 
458
              *owned = YES;
453
459
            }
454
460
          *length = len;
455
461
          *bytes = to;
456
 
          *shouldFree = YES;
457
462
        }
458
463
    }
459
464
}
460
465
 
461
466
- (id) initWithBytes: (const void*)bytes
462
 
              length: (unsigned int)length
 
467
              length: (NSUInteger)length
463
468
            encoding: (NSStringEncoding)encoding
464
469
{
465
470
  void          *chars = 0;
480
485
       */
481
486
      if (original == bytes)
482
487
        {
483
 
          chars = NSZoneMalloc(GSObjCZone(self), length);
 
488
#if     GS_WITH_GC
 
489
          chars = NSAllocateCollectable(length, 0);
 
490
#else
 
491
          chars = NSZoneMalloc([self zone], length);
 
492
#endif
484
493
          memcpy(chars, bytes, length);
485
494
        }
486
495
      else
499
508
}
500
509
 
501
510
- (id) initWithBytesNoCopy: (void*)bytes
502
 
                    length: (unsigned int)length
 
511
                    length: (NSUInteger)length
503
512
                  encoding: (NSStringEncoding)encoding
504
513
              freeWhenDone: (BOOL)flag
505
514
{
579
588
        }
580
589
    }
581
590
 
 
591
 
582
592
  if (encoding == internalEncoding)
583
593
    {
584
 
      me = (GSStr)NSAllocateObject(GSCBufferStringClass, 0, GSObjCZone(self));
 
594
#if     GS_WITH_GC
 
595
      /* If we are using GC, copy and free any non-collectable buffer so
 
596
       * we don't leak memory.
 
597
       */
 
598
      if (GSPrivateIsCollectable(chars.c) == NO)
 
599
        {
 
600
          me = (GSStr)NSAllocateObject(GSCInlineStringClass, length,
 
601
            [self zone]);
 
602
          me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1];
 
603
          me->_count = length;
 
604
          me->_flags.wide = 0;
 
605
          me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
 
606
          memcpy(me->_contents.c, chars.c, length);
 
607
          NSZoneFree(NSZoneFromPointer(chars.c), chars.c);
 
608
          return (id)me;
 
609
        }
 
610
#endif
 
611
      me = (GSStr)NSAllocateObject(GSCBufferStringClass, 0, [self zone]);
585
612
      me->_contents.c = chars.c;
586
613
      me->_count = length;
587
614
      me->_flags.wide = 0;
588
 
      me->_flags.free = flag;
 
615
      me->_flags.owned = flag;
589
616
      return (id)me;
590
617
    }
591
618
 
598
625
      unsigned  l = 0;
599
626
 
600
627
      if (GSToUnicode(&u, &l, chars.c, length, encoding,
601
 
        GSObjCZone(self), 0) == NO)
 
628
        [self zone], 0) == NO)
602
629
        {
603
630
          if (flag == YES && chars.c != 0)
604
631
            {
629
656
    || (internalEncoding == NSISOLatin1StringEncoding && isLatin1 == YES))
630
657
    {
631
658
      me = (GSStr)NSAllocateObject(GSCInlineStringClass, length,
632
 
        GSObjCZone(self));
633
 
      me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1];
 
659
        [self zone]);
 
660
      me->_contents.c = (unsigned char*)
 
661
        (((void*)me)+class_getInstanceSize(GSCInlineStringClass));
634
662
      me->_count = length;
635
663
      me->_flags.wide = 0;
636
 
      me->_flags.free = 1;      // Ignored on dealloc, but means we own buffer
 
664
      me->_flags.owned = 1;     // Ignored on dealloc, but means we own buffer
637
665
      while (length-- > 0)
638
666
        {
639
667
          me->_contents.c[length] = chars.u[length];
645
673
    }
646
674
  else
647
675
    {
 
676
#if     GS_WITH_GC
 
677
      /* If we are using GC, copy and free any non-collectable buffer so
 
678
       * we don't leak memory.
 
679
       */
 
680
      if (GSPrivateIsCollectable(chars.u) == NO)
 
681
        {
 
682
          me = (GSStr)NSAllocateObject(GSUnicodeInlineStringClass, length,
 
683
            [self zone]);
 
684
          me->_contents.u = (unichar*)&((GSUnicodeInlineString*)me)[1];
 
685
          me->_count = length;
 
686
          me->_flags.wide = 1;
 
687
          me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
 
688
          memcpy(me->_contents.u, chars.u, length * sizeof(unichar));
 
689
          NSZoneFree(NSZoneFromPointer(chars.u), chars.u);
 
690
          return (id)me;
 
691
        }
 
692
#endif
648
693
      me = (GSStr)NSAllocateObject(GSUnicodeBufferStringClass,
649
 
        0, GSObjCZone(self));
 
694
        0, [self zone]);
650
695
      me->_contents.u = chars.u;
651
696
      me->_count = length;
652
697
      me->_flags.wide = 1;
653
 
      me->_flags.free = flag;
 
698
      me->_flags.owned = flag;
654
699
    }
655
700
  return (id)me;
656
701
}
657
702
 
658
703
- (id) initWithCharacters: (const unichar*)chars
659
 
                   length: (unsigned)length
 
704
                   length: (NSUInteger)length
660
705
{
661
706
  return [self initWithBytes: (const void*)chars
662
707
                      length: length * sizeof(unichar)
664
709
}
665
710
 
666
711
- (id) initWithCharactersNoCopy: (unichar*)chars
667
 
                         length: (unsigned)length
 
712
                         length: (NSUInteger)length
668
713
                   freeWhenDone: (BOOL)flag
669
714
{
670
715
  return [self initWithBytesNoCopy: (void*)chars
674
719
}
675
720
 
676
721
- (id) initWithCString: (const char*)chars
677
 
                length: (unsigned)length
 
722
                length: (NSUInteger)length
678
723
{
679
724
  return [self initWithBytes: (const void*)chars
680
725
                      length: length
682
727
}
683
728
 
684
729
- (id) initWithCStringNoCopy: (char*)chars
685
 
                      length: (unsigned)length
 
730
                      length: (NSUInteger)length
686
731
                freeWhenDone: (BOOL)flag
687
732
{
688
733
  return [self initWithBytesNoCopy: (void*)chars
695
740
               locale: (NSDictionary*)locale
696
741
            arguments: (va_list)argList
697
742
{
 
743
  GSStr         f;
698
744
  unsigned char buf[2048];
699
 
  GSStr_t       f;
700
745
  unichar       fbuf[1024];
701
746
  unichar       *fmt = fbuf;
702
747
  size_t        len;
711
756
  len = [format length];
712
757
  if (len >= 1024)
713
758
    {
714
 
      fmt = objc_malloc((len+1)*sizeof(unichar));
 
759
      fmt = NSZoneMalloc(NSDefaultMallocZone(), (len+1)*sizeof(unichar));
715
760
    }
716
761
  [format getCharacters: fmt];
717
762
  fmt[len] = '\0';
720
765
   * Now set up 'f' as a GSMutableString object whose initial buffer is
721
766
   * allocated on the stack.  The GSPrivateFormat function can write into it.
722
767
   */
723
 
  f.isa = GSMutableStringClass;
724
 
  f._zone = NSDefaultMallocZone();
725
 
  f._contents.c = buf;
726
 
  f._capacity = sizeof(buf);
727
 
  f._count = 0;
728
 
  f._flags.wide = 0;
729
 
  f._flags.free = 0;
730
 
  GSPrivateFormat(&f, fmt, argList, locale);
 
768
  f = (GSStr)alloca(class_getInstanceSize(GSMutableStringClass));
 
769
  object_setClass(f, GSMutableStringClass);
 
770
  f->_zone = NSDefaultMallocZone();
 
771
  f->_contents.c = buf;
 
772
  f->_capacity = sizeof(buf);
 
773
  f->_count = 0;
 
774
  f->_flags.wide = 0;
 
775
  f->_flags.owned = 0;
 
776
  GSPrivateFormat(f, fmt, argList, locale);
731
777
  if (fmt != fbuf)
732
778
    {
733
 
      objc_free(fmt);
 
779
      NSZoneFree(NSDefaultMallocZone(), fmt);
734
780
    }
735
781
 
736
782
  /*
737
 
   * Don't use noCopy because f._contents.u may be memory on the stack,
738
 
   * and even if it wasn't f._capacity may be greater than f._count so
 
783
   * Don't use noCopy because f->_contents.u may be memory on the stack,
 
784
   * and even if it wasn't f->_capacity may be greater than f->_count so
739
785
   * we could be wasting quite a bit of space.  Better to accept a
740
786
   * performance hit due to copying data (and allocating/deallocating
741
787
   * the temporary buffer) for large strings.  For most strings, the
742
788
   * on-stack memory will have been used, so we will get better performance.
743
789
   */
744
 
  if (f._flags.wide == 1)
 
790
  if (f->_flags.wide == 1)
745
791
    {
746
792
      me = (GSStr)NSAllocateObject(GSUnicodeInlineStringClass,
747
 
        f._count*sizeof(unichar), GSObjCZone(self));
748
 
      me->_contents.u = (unichar*)&((GSUnicodeInlineString*)me)[1];
749
 
      me->_count = f._count;
 
793
        f->_count*sizeof(unichar), [self zone]);
 
794
      me->_contents.u = (unichar*)
 
795
        (((void*)me)+class_getInstanceSize(GSUnicodeInlineStringClass));
 
796
      me->_count = f->_count;
750
797
      me->_flags.wide = 1;
751
 
      me->_flags.free = 1;      // Ignored on dealloc, but means we own buffer
752
 
      memcpy(me->_contents.u, f._contents.u, f._count*sizeof(unichar));
 
798
      me->_flags.owned = 1;     // Ignored on dealloc, but means we own buffer
 
799
      memcpy(me->_contents.u, f->_contents.u, f->_count*sizeof(unichar));
753
800
    }
754
801
  else
755
802
    {
756
 
      me = (GSStr)NSAllocateObject(GSCInlineStringClass, f._count,
757
 
        GSObjCZone(self));
758
 
      me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1];
759
 
      me->_count = f._count;
 
803
      me = (GSStr)NSAllocateObject(GSCInlineStringClass, f->_count,
 
804
        [self zone]);
 
805
      me->_contents.c = (unsigned char*)
 
806
        (((void*)me)+class_getInstanceSize(GSCInlineStringClass));
 
807
      me->_count = f->_count;
760
808
      me->_flags.wide = 0;
761
 
      me->_flags.free = 1;      // Ignored on dealloc, but means we own buffer
762
 
      memcpy(me->_contents.c, f._contents.c, f._count);
 
809
      me->_flags.owned = 1;     // Ignored on dealloc, but means we own buffer
 
810
      memcpy(me->_contents.c, f->_contents.c, f->_count);
763
811
    }
764
812
 
765
813
  /*
766
814
   * If the string had to grow beyond the initial buffer size, we must
767
815
   * release any allocated memory.
768
816
   */
769
 
  if (f._flags.free == 1)
 
817
  if (f->_flags.owned == 1)
770
818
    {
771
 
      NSZoneFree(f._zone, f._contents.c);
 
819
      NSZoneFree(f->_zone, f->_contents.c);
772
820
    }
773
821
  return (id)me;
774
822
}
786
834
  if (string == nil)
787
835
    [NSException raise: NSInvalidArgumentException
788
836
                format: @"-initWithString: given nil string"];
789
 
  c = GSObjCClass(string);
790
 
  if (GSObjCIsKindOf(c, NSStringClass) == NO)
 
837
  if (NO == [string isKindOfClass: NSStringClass])      // may be proxy
791
838
    [NSException raise: NSInvalidArgumentException
792
839
                format: @"-initWithString: given non-string object"];
793
840
 
 
841
  c = object_getClass(string);
794
842
  length = [string length];
795
843
  if (GSObjCIsKindOf(c, GSCStringClass) == YES || c == NSConstantStringClass
796
844
    || (GSObjCIsKindOf(c, GSMutableStringClass) == YES
801
849
       * GSMutableString, we can copy the bytes directly into a GSCString.
802
850
       */
803
851
      me = (GSStr)NSAllocateObject(GSCInlineStringClass,
804
 
        length, GSObjCZone(self));
805
 
      me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1];
 
852
        length, [self zone]);
 
853
      me->_contents.c = (unsigned char*)
 
854
        (((void*)me)+class_getInstanceSize(GSCInlineStringClass));
806
855
      me->_count = length;
807
856
      me->_flags.wide = 0;
808
 
      me->_flags.free = 1;      // Ignored on dealloc, but means we own buffer
 
857
      me->_flags.owned = 1;     // Ignored on dealloc, but means we own buffer
809
858
      memcpy(me->_contents.c, ((GSStr)string)->_contents.c, length);
810
859
    }
811
860
  else if (GSObjCIsKindOf(c, GSUnicodeStringClass) == YES
816
865
       * we can copy the bytes directly into a GSUnicodeString.
817
866
       */
818
867
      me = (GSStr)NSAllocateObject(GSUnicodeInlineStringClass,
819
 
        length*sizeof(unichar), GSObjCZone(self));
820
 
      me->_contents.u = (unichar*)&((GSUnicodeInlineString*)me)[1];
 
868
        length*sizeof(unichar), [self zone]);
 
869
      me->_contents.u = (unichar*)
 
870
        (((void*)me)+class_getInstanceSize(GSUnicodeInlineStringClass));
821
871
      me->_count = length;
822
872
      me->_flags.wide = 1;
823
 
      me->_flags.free = 1;      // Ignored on dealloc, but means we own buffer
 
873
      me->_flags.owned = 1;     // Ignored on dealloc, but means we own buffer
824
874
      memcpy(me->_contents.u, ((GSStr)string)->_contents.u,
825
875
        length*sizeof(unichar));
826
876
    }
831
881
       * having the string copy its content directly into our buffer.
832
882
       */
833
883
      me = (GSStr)NSAllocateObject(GSUnicodeInlineStringClass,
834
 
        length*sizeof(unichar), GSObjCZone(self));
835
 
      me->_contents.u = (unichar*)&((GSUnicodeInlineString*)me)[1];
 
884
        length*sizeof(unichar), [self zone]);
 
885
      me->_contents.u = (unichar*)
 
886
        (((void*)me)+class_getInstanceSize(GSUnicodeInlineStringClass));
836
887
      me->_count = length;
837
888
      me->_flags.wide = 1;
838
 
      me->_flags.free = 1;      // Ignored on dealloc, but means we own buffer
 
889
      me->_flags.owned = 1;     // Ignored on dealloc, but means we own buffer
839
890
      [string getCharacters: me->_contents.u];
840
891
    }
841
892
  return (id)me;
842
893
}
843
894
 
844
 
- (unsigned) length
 
895
- (NSUInteger) length
845
896
{
846
897
  [NSException raise: NSInternalInconsistencyException
847
898
              format: @"attempt to use uninitialised string"];
957
1008
 
958
1009
  for (i = 0; i < c; i++)
959
1010
    {
960
 
      if (strchr("123456789yYtT", self->_contents.c[i]) != 0)
 
1011
      char      c = self->_contents.c[i];
 
1012
 
 
1013
      if (strchr("123456789yYtT", c) != 0)
961
1014
        {
962
1015
          return YES;
963
1016
        }
 
1017
      if (!isspace(c) && c != '0' && c != '-' && c != '+')
 
1018
        {
 
1019
          break;
 
1020
        }
964
1021
    }
965
1022
  return NO;
966
1023
}
973
1030
 
974
1031
  for (i = 0; i < c; i++)
975
1032
    {
976
 
      if (strchr("123456789yYtT", self->_contents.u[i]) != 0)
 
1033
      unichar   c = self->_contents.u[i];
 
1034
 
 
1035
      if (c > 'y')
 
1036
        {
 
1037
          break;
 
1038
        }
 
1039
      if (strchr("123456789yYtT", c) != 0)
977
1040
        {
978
1041
          return YES;
979
1042
        }
 
1043
      if (!isspace(c) && c != '0' && c != '-' && c != '+')
 
1044
        {
 
1045
          break;
 
1046
        }
980
1047
    }
981
1048
  return NO;
982
1049
}
1155
1222
{
1156
1223
  Class c;
1157
1224
 
1158
 
  c = GSObjCClass(aString);
 
1225
  c = object_getClass(aString);
1159
1226
  if (GSObjCIsKindOf(c, GSUnicodeStringClass) == YES
1160
1227
    || (c == GSMutableStringClass && ((GSStr)aString)->_flags.wide == 1))
1161
1228
    return strCompCsUs((id)self, aString, mask, aRange);
1172
1239
{
1173
1240
  Class c;
1174
1241
 
1175
 
  c = GSObjCClass(aString);
 
1242
  c = object_getClass(aString);
1176
1243
  if (GSObjCIsKindOf(c, GSUnicodeStringClass)
1177
1244
    || (c == GSMutableStringClass && ((GSStr)aString)->_flags.wide == 1))
1178
1245
    return strCompUsUs((id)self, aString, mask, aRange);
1588
1655
getCString_c(GSStr self, char *buffer, unsigned int maxLength,
1589
1656
  NSRange aRange, NSRange *leftoverRange)
1590
1657
{
 
1658
  GSMutableString *o;
1591
1659
  int len;
1592
1660
 
1593
 
  /*
1594
 
   * If the internal and external encodings don't match, the simplest
1595
 
   * thing to do is widen the internal data to unicode and use the
1596
 
   * unicode function to get the cString.
1597
 
   */
1598
 
  if (externalEncoding != internalEncoding)
1599
 
    {
1600
 
      struct {
1601
 
        @defs(GSMutableString)
1602
 
      } o;
1603
 
 
1604
 
      memset(&o, '\0', sizeof(o));
1605
 
      o._count = self->_count;
1606
 
      o._capacity = self->_count;
1607
 
      o._contents.c = self->_contents.c;
1608
 
      GSStrWiden((GSStr)&o);
1609
 
      getCString_u((GSStr)&o, buffer, maxLength, aRange, leftoverRange);
1610
 
      if (o._flags.free == 1)
1611
 
        {
1612
 
          NSZoneFree(o._zone, o._contents.u);
1613
 
        }
1614
 
      return;
1615
 
    }
1616
 
 
1617
1661
  if (maxLength > self->_count)
1618
1662
    {
1619
1663
      maxLength = self->_count;
1637
1681
        }
1638
1682
    }
1639
1683
 
1640
 
  memcpy(buffer, &self->_contents.c[aRange.location], len);
1641
 
  buffer[len] = '\0';
 
1684
  if (externalEncoding == internalEncoding)
 
1685
    {
 
1686
      memcpy(buffer, &self->_contents.c[aRange.location], len);
 
1687
      buffer[len] = '\0';
 
1688
      return;
 
1689
    }
 
1690
 
 
1691
  if (isByteEncoding(internalEncoding))
 
1692
    {
 
1693
      if (externalEncoding == NSUTF8StringEncoding
 
1694
        || isByteEncoding(externalEncoding))
 
1695
        {
 
1696
          const unsigned char   *ptr = self->_contents.c + aRange.location;
 
1697
          unsigned              i;
 
1698
 
 
1699
          /*
 
1700
           * Maybe we actually contain ascii data, which can be
 
1701
           * copied out directly.
 
1702
           */
 
1703
          for (i = 0; i < len; i++)
 
1704
            {
 
1705
              unsigned char     c = ptr[i];
 
1706
 
 
1707
              if (c > 127)
 
1708
                {
 
1709
                  break;
 
1710
                }
 
1711
              buffer[i] = c;
 
1712
            }
 
1713
          if (i == len)
 
1714
            {
 
1715
              buffer[i] = '\0';
 
1716
              return;
 
1717
            }
 
1718
          // Fall through to perform conversion to unicode and back
 
1719
          if ([(id)self class] == NSConstantStringClass)
 
1720
            {
 
1721
              NSLog(@"Warning: non-ASCII character in string literal");
 
1722
            }
 
1723
        }
 
1724
    }
 
1725
 
 
1726
  /* As the internal and external encodings don't match, the simplest
 
1727
   * thing to do is widen the internal data to unicode and use the
 
1728
   * unicode function to get the cString.
 
1729
   */
 
1730
  o = (GSMutableString*)alloca(class_getInstanceSize(GSMutableStringClass));
 
1731
  object_setClass(o, GSMutableStringClass);
 
1732
  o->_count = self->_count;
 
1733
  o->_flags.wide = 0;
 
1734
  o->_flags.owned = 0;
 
1735
  o->_flags.unused = 0;
 
1736
  o->_flags.hash = 0;
 
1737
  o->_capacity = self->_count;
 
1738
  o->_contents.c = self->_contents.c;
 
1739
  o->_zone = NSDefaultMallocZone();
 
1740
  GSStrWiden(o);
 
1741
  getCString_u(o, buffer, maxLength, aRange, leftoverRange);
 
1742
  if (o->_flags.owned == 1)
 
1743
    {
 
1744
      NSZoneFree(o->_zone, o->_contents.u);
 
1745
    }
1642
1746
}
1643
1747
 
1644
1748
static void
2042
2146
    {
2043
2147
      return NO;
2044
2148
    }
2045
 
  c = GSObjCClass(anObject);
 
2149
  c = object_getClass(anObject);
2046
2150
  if (c == NSConstantStringClass)
2047
2151
    {
2048
2152
      GSStr     other = (GSStr)anObject;
2049
 
      NSRange   r = {0, self->_count};
2050
2153
 
2051
 
      if (strCompCsCs((id)self, (id)other, 0, r) == NSOrderedSame)
 
2154
      if (other->_count == self->_count
 
2155
        && memcmp(other->_contents.c, self->_contents.c, self->_count) == 0)
2052
2156
        return YES;
2053
2157
      return NO;
2054
2158
    }
2055
 
  else if (GSObjCIsKindOf(c, GSStringClass) == YES || c == GSMutableStringClass)
 
2159
  else if (c == GSMutableStringClass || GSObjCIsKindOf(c, GSStringClass) == YES)
2056
2160
    {
2057
2161
      GSStr     other = (GSStr)anObject;
2058
2162
      NSRange   r = {0, self->_count};
2077
2181
        }
2078
2182
      else
2079
2183
        {
2080
 
          if (strCompCsCs((id)self, (id)other, 0, r) == NSOrderedSame)
 
2184
          if (other->_count == self->_count
 
2185
            && memcmp(other->_contents.c, self->_contents.c, self->_count) == 0)
2081
2186
            return YES;
2082
2187
        }
2083
2188
      return NO;
2084
2189
    }
2085
 
  else if (GSObjCIsKindOf(c, NSStringClass))
 
2190
  else if (YES == [anObject isKindOfClass: NSStringClass]) // may be proxy
2086
2191
    {
2087
2192
      return (*equalImp)((id)self, equalSel, anObject);
2088
2193
    }
2109
2214
    {
2110
2215
      return NO;
2111
2216
    }
2112
 
  c = GSObjCClass(anObject);
 
2217
  c = object_getClass(anObject);
2113
2218
  if (c == NSConstantStringClass)
2114
2219
    {
2115
2220
      GSStr     other = (GSStr)anObject;
2119
2224
        return YES;
2120
2225
      return NO;
2121
2226
    }
2122
 
  else if (GSObjCIsKindOf(c, GSStringClass) == YES || c == GSMutableStringClass)
 
2227
  else if (c == GSMutableStringClass || GSObjCIsKindOf(c, GSStringClass) == YES)
2123
2228
    {
2124
2229
      GSStr     other = (GSStr)anObject;
2125
2230
      NSRange   r = {0, self->_count};
2149
2254
        }
2150
2255
      return NO;
2151
2256
    }
2152
 
  else if (GSObjCIsKindOf(c, NSStringClass))
 
2257
  else if (YES == [anObject isKindOfClass: NSStringClass]) // may be proxy
2153
2258
    {
2154
2259
      return (*equalImp)((id)self, equalSel, anObject);
2155
2260
    }
2229
2334
    {
2230
2335
      s->_capacity = want;
2231
2336
    }
2232
 
  if (s->_flags.free == 1)
 
2337
  if (s->_flags.owned == 1)
2233
2338
    {
2234
2339
      /*
2235
2340
       * If we own the character buffer, we can simply realloc.
2256
2361
#if     GS_WITH_GC
2257
2362
          s->_zone = GSAtomicMallocZone();
2258
2363
#else
2259
 
          if (s->isa == 0)
2260
 
            {
2261
 
              s->_zone = NSDefaultMallocZone();
2262
 
            }
2263
 
          else
2264
 
            {
2265
 
              s->_zone = GSObjCZone((NSString*)s);
2266
 
            }
 
2364
          s->_zone = [(NSString*)s zone];
2267
2365
#endif
2268
2366
        }
2269
2367
      if (s->_flags.wide == 1)
2287
2385
              memcpy(s->_contents.c, tmp, s->_count);
2288
2386
            }
2289
2387
        }
2290
 
      s->_flags.free = 1;
 
2388
      s->_flags.owned = 1;
2291
2389
    }
2292
2390
}
2293
2391
 
2324
2422
#if GS_WITH_GC
2325
2423
      s->_zone = GSAtomicMallocZone();
2326
2424
#else
2327
 
      if (s->isa == 0)
2328
 
        {
2329
 
          s->_zone = NSDefaultMallocZone();
2330
 
        }
2331
 
      else
2332
 
        {
2333
 
          s->_zone = GSObjCZone((NSString*)s);
2334
 
        }
 
2425
      s->_zone = [(NSString*)s zone];
2335
2426
#endif
2336
2427
    }
2337
2428
 
2341
2432
      [NSException raise: NSInternalInconsistencyException
2342
2433
                  format: @"widen of string failed"];
2343
2434
    }
2344
 
  if (s->_flags.free == 1)
 
2435
  if (s->_flags.owned == 1)
2345
2436
    {
2346
2437
      NSZoneFree(s->_zone, s->_contents.c);
2347
2438
    }
2348
2439
  else
2349
2440
    {
2350
 
      s->_flags.free = 1;
 
2441
      s->_flags.owned = 1;
2351
2442
    }
2352
2443
  s->_contents.u = tmp;
2353
2444
  s->_flags.wide = 1;
2519
2610
{
2520
2611
  Class c;
2521
2612
 
2522
 
  c = GSObjCClass(receiver);
 
2613
  c = object_getClass(receiver);
2523
2614
  if (GSObjCIsKindOf(c, GSUnicodeStringClass) == YES
2524
2615
    || (c == GSMutableStringClass && ((GSStr)receiver)->_flags.wide == 1))
2525
2616
    {
2526
 
      c = GSObjCClass(target);
 
2617
      c = object_getClass(target);
2527
2618
      if (GSObjCIsKindOf(c, GSUnicodeStringClass) == YES
2528
2619
        || (c == GSMutableStringClass && ((GSStr)target)->_flags.wide == 1))
2529
2620
        return (GSRSFunc)strRangeUsUs;
2538
2629
    || c == NSConstantStringClass
2539
2630
    || (c == GSMutableStringClass && ((GSStr)target)->_flags.wide == 0))
2540
2631
    {
2541
 
      c = GSObjCClass(target);
 
2632
      c = object_getClass(target);
2542
2633
      if (GSObjCIsKindOf(c, GSUnicodeStringClass) == YES
2543
2634
        || (c == GSMutableStringClass && ((GSStr)target)->_flags.wide == 1))
2544
2635
        return (GSRSFunc)strRangeCsUs;
2560
2651
{
2561
2652
  Class c;
2562
2653
 
2563
 
  c = GSObjCClass(aString);
 
2654
  c = object_getClass(aString);
2564
2655
  if (GSObjCIsKindOf(c, GSUnicodeStringClass) == YES
2565
2656
    || (c == GSMutableStringClass && ((GSStr)aString)->_flags.wide == 1))
2566
2657
    return strRangeCsUs((id)self, aString, mask, aRange);
2577
2668
{
2578
2669
  Class c;
2579
2670
 
2580
 
  c = GSObjCClass(aString);
 
2671
  c = object_getClass(aString);
2581
2672
  if (GSObjCIsKindOf(c, GSUnicodeStringClass) == YES
2582
2673
    || (c == GSMutableStringClass && ((GSStr)aString)->_flags.wide == 1))
2583
2674
    return strRangeUsUs((id)self, aString, mask, aRange);
2592
2683
static inline NSString*
2593
2684
substring_c(GSStr self, NSRange aRange)
2594
2685
{
2595
 
  GSSubstringStruct     *o;
 
2686
  GSCSubString  *o;
2596
2687
 
2597
2688
  if (aRange.length == 0)
2598
2689
    {
2603
2694
  o->_contents.c = self->_contents.c + aRange.location;
2604
2695
  o->_count = aRange.length;
2605
2696
  o->_flags.wide = 0;
2606
 
  o->_flags.free = 0;
2607
 
  ASSIGN(o->_parent, self);
2608
 
  AUTORELEASE((id)o);
2609
 
  return (id)o;
 
2697
  o->_flags.owned = 0;
 
2698
  ASSIGN(o->_parent, (id)self);
 
2699
  return AUTORELEASE((id)o);
2610
2700
}
2611
2701
 
2612
2702
static inline NSString*
2613
2703
substring_u(GSStr self, NSRange aRange)
2614
2704
{
2615
 
  GSSubstringStruct     *o;
 
2705
  GSCSubString  *o;
2616
2706
 
2617
2707
  if (aRange.length == 0)
2618
2708
    {
2623
2713
  o->_contents.u = self->_contents.u + aRange.location;
2624
2714
  o->_count = aRange.length;
2625
2715
  o->_flags.wide = 1;
2626
 
  o->_flags.free = 0;
2627
 
  ASSIGN(o->_parent, self);
2628
 
  AUTORELEASE((id)o);
2629
 
  return (id)o;
 
2716
  o->_flags.owned = 0;
 
2717
  ASSIGN(o->_parent, (id)self);
 
2718
  return AUTORELEASE((id)o);
2630
2719
}
2631
2720
 
2632
2721
/*
2641
2730
{
2642
2731
  GSStr other = (GSStr)aString;
2643
2732
  BOOL  transmute = YES;
2644
 
  Class c = GSObjCClass(aString);       // NB aString must not be nil
 
2733
  Class c = object_getClass(aString);   // NB aString must not be nil
2645
2734
 
2646
2735
  if (self->_flags.wide == 1)
2647
2736
    {
2731
2820
  setup();
2732
2821
}
2733
2822
 
2734
 
- (void) dealloc
 
2823
/*
 
2824
 * Return a 28-bit hash value for the string contents - this
 
2825
 * MUST match the algorithm used by the NSString base class.
 
2826
 */
 
2827
- (NSUInteger) hash
2735
2828
{
2736
 
  [self subclassResponsibility: _cmd];
2737
 
  GSNOSUPERDEALLOC;
 
2829
  if (self->_flags.hash == 0)
 
2830
    {
 
2831
      unsigned  ret = 0;
 
2832
      unsigned  len = self->_count;
 
2833
 
 
2834
      if (len > 0)
 
2835
        {
 
2836
          register unsigned     index = 0;
 
2837
 
 
2838
          if (self->_flags.wide)
 
2839
            {
 
2840
              register const unichar    *p = self->_contents.u;
 
2841
 
 
2842
              while (index < len)
 
2843
                {
 
2844
                  ret = (ret << 5) + ret + p[index++];
 
2845
                }
 
2846
            }
 
2847
          else
 
2848
            {
 
2849
              register const unsigned char      *p = self->_contents.c;
 
2850
 
 
2851
              if (internalEncoding == NSISOLatin1StringEncoding)
 
2852
                {
 
2853
                  while (index < len)
 
2854
                    {
 
2855
                      ret = (ret << 5) + ret + p[index++];
 
2856
                    }
 
2857
                }
 
2858
              else
 
2859
                {
 
2860
                  while (index < len)
 
2861
                    {
 
2862
                      unichar   u = p[index++];
 
2863
 
 
2864
                      if (u > 127)
 
2865
                        {
 
2866
                          unsigned char c = (unsigned char)u;
 
2867
                          unsigned int  s = 1;
 
2868
                          unichar       *d = &u;
 
2869
 
 
2870
                          GSToUnicode(&d, &s, &c, 1, internalEncoding, 0, 0);
 
2871
                        }
 
2872
                      ret = (ret << 5) + ret + u;
 
2873
                    }
 
2874
                }
 
2875
            }
 
2876
 
 
2877
          /*
 
2878
           * The hash caching in our concrete string classes uses zero to denote
 
2879
           * an empty cache value, so we MUST NOT return a hash of zero.
 
2880
           */
 
2881
          ret &= 0x0fffffff;
 
2882
          if (ret == 0)
 
2883
            {
 
2884
              ret = 0x0fffffff;
 
2885
            }
 
2886
        }
 
2887
      else
 
2888
        {
 
2889
          ret = 0x0ffffffe;     /* Hash for an empty string.    */
 
2890
        }
 
2891
      self->_flags.hash = ret;
 
2892
    }
 
2893
 
 
2894
  return self->_flags.hash;
2738
2895
}
2739
2896
 
2740
2897
- (id) initWithBytes: (const void*)chars
2741
 
              length: (unsigned int)length
 
2898
              length: (NSUInteger)length
2742
2899
            encoding: (NSStringEncoding)encoding
2743
2900
{
2744
2901
  if (length > 0)
2745
2902
    {
2746
 
      void      *tmp = NSZoneMalloc(GSObjCZone(self), length);
 
2903
      void      *tmp = NSZoneMalloc([self zone], length);
2747
2904
 
2748
2905
      memcpy(tmp, chars, length);
2749
2906
      chars = tmp;
2755
2912
}
2756
2913
 
2757
2914
- (id) initWithBytesNoCopy: (void*)chars
2758
 
                    length: (unsigned int)length
 
2915
                    length: (NSUInteger)length
2759
2916
                  encoding: (NSStringEncoding)encoding
2760
2917
              freeWhenDone: (BOOL)flag
2761
2918
{
2762
2919
  NSString      *c = NSStringFromClass([self class]);
2763
2920
  NSString      *s = NSStringFromSelector(_cmd);
2764
2921
 
2765
 
  RELEASE(self);
 
2922
  DESTROY(self);
2766
2923
  [NSException raise: NSInternalInconsistencyException
2767
2924
              format: @"[%@-%@] called on string already initialised", c, s];
2768
2925
  return nil;
2769
2926
}
2770
2927
 
2771
2928
- (id) initWithCharacters: (const unichar*)chars
2772
 
                   length: (unsigned int)length
 
2929
                   length: (NSUInteger)length
2773
2930
{
2774
2931
  return [self initWithBytes: chars
2775
2932
                      length: length * sizeof(unichar)
2777
2934
}
2778
2935
 
2779
2936
- (id) initWithCharactersNoCopy: (unichar*)chars
2780
 
                         length: (unsigned int)length
 
2937
                         length: (NSUInteger)length
2781
2938
                   freeWhenDone: (BOOL)flag
2782
2939
{
2783
2940
  return [self initWithBytesNoCopy: chars
2802
2959
}
2803
2960
 
2804
2961
- (id) initWithCString: (const char*)chars
2805
 
                length: (unsigned int)length
 
2962
                length: (NSUInteger)length
2806
2963
{
2807
2964
  return [self initWithBytes: chars
2808
2965
                      length: length
2810
2967
}
2811
2968
 
2812
2969
- (id) initWithCStringNoCopy: (char*)chars
2813
 
                      length: (unsigned int)length
 
2970
                      length: (NSUInteger)length
2814
2971
                freeWhenDone: (BOOL)flag
2815
2972
{
2816
2973
  return [self initWithBytesNoCopy: chars
2845
3002
  return canBeConvertedToEncoding_c((GSStr)self, enc);
2846
3003
}
2847
3004
 
2848
 
- (unichar) characterAtIndex: (unsigned int)index
 
3005
- (unichar) characterAtIndex: (NSUInteger)index
2849
3006
{
2850
3007
  return characterAtIndex_c((GSStr)self, index);
2851
3008
}
2852
3009
 
2853
3010
- (NSComparisonResult) compare: (NSString*)aString
2854
 
                       options: (unsigned int)mask
 
3011
                       options: (NSUInteger)mask
2855
3012
                         range: (NSRange)aRange
2856
3013
{
2857
3014
  GS_RANGE_CHECK(aRange, _count);
2876
3033
  return cString_c((GSStr)self, encoding);
2877
3034
}
2878
3035
 
2879
 
- (unsigned int) cStringLength
 
3036
- (NSUInteger) cStringLength
2880
3037
{
2881
3038
  return cStringLength_c((GSStr)self, externalEncoding);
2882
3039
}
2939
3096
}
2940
3097
 
2941
3098
- (void) getCString: (char*)buffer
2942
 
          maxLength: (unsigned int)maxLength
 
3099
          maxLength: (NSUInteger)maxLength
2943
3100
{
2944
3101
  getCString_c((GSStr)self, buffer, maxLength, (NSRange){0, _count}, 0);
2945
3102
}
2946
3103
 
2947
3104
- (BOOL) getCString: (char*)buffer
2948
 
          maxLength: (unsigned int)maxLength
 
3105
          maxLength: (NSUInteger)maxLength
2949
3106
           encoding: (NSStringEncoding)encoding
2950
3107
{
2951
3108
  return getCStringE_c((GSStr)self, buffer, maxLength, encoding);
2952
3109
}
2953
3110
 
2954
3111
- (void) getCString: (char*)buffer
2955
 
          maxLength: (unsigned int)maxLength
 
3112
          maxLength: (NSUInteger)maxLength
2956
3113
              range: (NSRange)aRange
2957
3114
     remainingRange: (NSRange*)leftoverRange
2958
3115
{
2960
3117
  getCString_c((GSStr)self, buffer, maxLength, aRange, leftoverRange);
2961
3118
}
2962
3119
 
2963
 
- (unsigned) hash
2964
 
{
2965
 
  if (self->_flags.hash == 0)
2966
 
    {
2967
 
      self->_flags.hash = (*hashImp)((id)self, hashSel);
2968
 
    }
2969
 
  return self->_flags.hash;
2970
 
}
2971
 
 
2972
 
- (int) intValue
 
3120
- (NSInteger) intValue
2973
3121
{
2974
3122
  return intValue_c((GSStr)self);
2975
3123
}
2984
3132
  return isEqual_c((GSStr)self, anObject);
2985
3133
}
2986
3134
 
2987
 
- (unsigned int) length
 
3135
- (NSUInteger) length
2988
3136
{
2989
3137
  return _count;
2990
3138
}
2991
3139
 
2992
 
- (unsigned int) lengthOfBytesUsingEncoding: (NSStringEncoding)encoding
 
3140
- (NSUInteger) lengthOfBytesUsingEncoding: (NSStringEncoding)encoding
2993
3141
{
2994
3142
  return cStringLength_c((GSStr)self, encoding);
2995
3143
}
3022
3170
  return obj;
3023
3171
}
3024
3172
 
3025
 
- (NSRange) rangeOfComposedCharacterSequenceAtIndex: (unsigned)anIndex
 
3173
- (NSRange) rangeOfComposedCharacterSequenceAtIndex: (NSUInteger)anIndex
3026
3174
{
3027
3175
  return rangeOfSequence_c((GSStr)self, anIndex);
3028
3176
}
3029
3177
 
3030
3178
- (NSRange) rangeOfCharacterFromSet: (NSCharacterSet*)aSet
3031
 
                            options: (unsigned)mask
 
3179
                            options: (NSUInteger)mask
3032
3180
                              range: (NSRange)aRange
3033
3181
{
3034
3182
  GS_RANGE_CHECK(aRange, _count);
3036
3184
}
3037
3185
 
3038
3186
- (NSRange) rangeOfString: (NSString*)aString
3039
 
                  options: (unsigned)mask
 
3187
                  options: (NSUInteger)mask
3040
3188
                    range: (NSRange)aRange
3041
3189
{
3042
3190
  GS_RANGE_CHECK(aRange, _count);
3069
3217
}
3070
3218
 
3071
3219
// private method for Unicode level 3 implementation
3072
 
- (int) _baseLength
 
3220
- (NSInteger) _baseLength
3073
3221
{
3074
3222
  return _count;
3075
3223
}
3080
3228
*/
3081
3229
- (id) copyWithZone: (NSZone*)z
3082
3230
{
3083
 
  if (!_flags.free || NSShouldRetainWithZone(self, z) == NO)
 
3231
  if (!_flags.owned || NSShouldRetainWithZone(self, z) == NO)
3084
3232
    {
3085
 
      struct {
3086
 
        @defs(GSCInlineString)
3087
 
      } *o;
 
3233
      GSCInlineString *o;
3088
3234
 
3089
3235
      o = (typeof(o))NSAllocateObject(GSCInlineStringClass, _count, z);
3090
 
      o->_contents.c = (unsigned char*)&o[1];
 
3236
      o->_contents.c = (unsigned char*)
 
3237
        (((void*)o)+class_getInstanceSize(GSCInlineStringClass));
3091
3238
      o->_count = _count;
3092
3239
      memcpy(o->_contents.c, _contents.c, _count);
3093
3240
      o->_flags.wide = 0;
3094
 
      o->_flags.free = 1;       // Ignored on dealloc, but means we own buffer
 
3241
      o->_flags.owned = 1;      // Ignored on dealloc, but means we own buffer
3095
3242
      return (id)o;
3096
3243
    }
3097
3244
  else
3107
3254
@implementation GSCBufferString
3108
3255
- (void) dealloc
3109
3256
{
3110
 
  if (_flags.free && _contents.c != 0)
 
3257
  if (_contents.c != 0)
3111
3258
    {
3112
 
      NSZoneFree(NSZoneFromPointer(_contents.c), _contents.c);
 
3259
      if (_flags.owned)
 
3260
        {
 
3261
          NSZoneFree(NSZoneFromPointer(_contents.c), _contents.c);
 
3262
        }
3113
3263
      _contents.c = 0;
3114
3264
    }
3115
 
  NSDeallocateObject(self);
3116
 
  GSNOSUPERDEALLOC;
 
3265
  [super dealloc];
3117
3266
}
3118
3267
@end
3119
3268
 
3120
3269
 
3121
3270
 
3122
3271
@implementation GSCInlineString
3123
 
- (void) dealloc
3124
 
{
3125
 
  NSDeallocateObject(self);
3126
 
  GSNOSUPERDEALLOC;
3127
 
}
3128
3272
@end
3129
3273
 
3130
3274
 
3136
3280
 */
3137
3281
- (id) copyWithZone: (NSZone*)z
3138
3282
{
3139
 
  struct {
3140
 
    @defs(GSCInlineString)
3141
 
  } *o;
 
3283
  GSCInlineString *o;
3142
3284
 
3143
3285
  o = (typeof(o))NSAllocateObject(GSCInlineStringClass, _count, z);
3144
 
  o->_contents.c = (unsigned char*)&o[1];
 
3286
  o->_contents.c = (unsigned char*)
 
3287
    (((void*)o)+class_getInstanceSize(GSCInlineStringClass));
3145
3288
  o->_count = _count;
3146
3289
  memcpy(o->_contents.c, _contents.c, _count);
3147
3290
  o->_flags.wide = 0;
3148
 
  o->_flags.free = 1;   // Ignored on dealloc, but means we own buffer
 
3291
  o->_flags.owned = 1;  // Ignored on dealloc, but means we own buffer
3149
3292
  return (id)o;
3150
3293
}
3151
3294
 
3152
3295
- (void) dealloc
3153
3296
{
3154
3297
  DESTROY(_parent);
3155
 
  NSDeallocateObject(self);
3156
 
  GSNOSUPERDEALLOC;
 
3298
  [super dealloc];
3157
3299
}
3158
3300
@end
3159
3301
 
3175
3317
  return canBeConvertedToEncoding_u((GSStr)self, enc);
3176
3318
}
3177
3319
 
3178
 
- (unichar) characterAtIndex: (unsigned int)index
 
3320
- (unichar) characterAtIndex: (NSUInteger)index
3179
3321
{
3180
3322
  return characterAtIndex_u((GSStr)self, index);
3181
3323
}
3182
3324
 
3183
3325
- (NSComparisonResult) compare: (NSString*)aString
3184
 
                       options: (unsigned int)mask
 
3326
                       options: (NSUInteger)mask
3185
3327
                         range: (NSRange)aRange
3186
3328
{
3187
3329
  GS_RANGE_CHECK(aRange, _count);
3206
3348
  return cString_u((GSStr)self, encoding);
3207
3349
}
3208
3350
 
3209
 
- (unsigned int) cStringLength
 
3351
- (NSUInteger) cStringLength
3210
3352
{
3211
3353
  return cStringLength_u((GSStr)self, externalEncoding);
3212
3354
}
3270
3412
}
3271
3413
 
3272
3414
- (void) getCString: (char*)buffer
3273
 
          maxLength: (unsigned int)maxLength
 
3415
          maxLength: (NSUInteger)maxLength
3274
3416
{
3275
3417
  getCString_u((GSStr)self, buffer, maxLength, (NSRange){0, _count}, 0);
3276
3418
}
3277
3419
 
3278
3420
- (BOOL) getCString: (char*)buffer
3279
 
          maxLength: (unsigned int)maxLength
 
3421
          maxLength: (NSUInteger)maxLength
3280
3422
           encoding: (NSStringEncoding)encoding
3281
3423
{
3282
3424
  return getCStringE_u((GSStr)self, buffer, maxLength, encoding);
3283
3425
}
3284
3426
- (void) getCString: (char*)buffer
3285
 
          maxLength: (unsigned int)maxLength
 
3427
          maxLength: (NSUInteger)maxLength
3286
3428
              range: (NSRange)aRange
3287
3429
     remainingRange: (NSRange*)leftoverRange
3288
3430
{
3291
3433
  getCString_u((GSStr)self, buffer, maxLength, aRange, leftoverRange);
3292
3434
}
3293
3435
 
3294
 
- (unsigned) hash
3295
 
{
3296
 
  if (self->_flags.hash == 0)
3297
 
    {
3298
 
      self->_flags.hash = (*hashImp)((id)self, hashSel);
3299
 
    }
3300
 
  return self->_flags.hash;
3301
 
}
3302
 
 
3303
 
- (int) intValue
 
3436
- (NSInteger) intValue
3304
3437
{
3305
3438
  return intValue_u((GSStr)self);
3306
3439
}
3315
3448
  return isEqual_u((GSStr)self, anObject);
3316
3449
}
3317
3450
 
3318
 
- (unsigned int) length
 
3451
- (NSUInteger) length
3319
3452
{
3320
3453
  return _count;
3321
3454
}
3322
3455
 
3323
 
- (unsigned int) lengthOfBytesUsingEncoding: (NSStringEncoding)encoding
 
3456
- (NSUInteger) lengthOfBytesUsingEncoding: (NSStringEncoding)encoding
3324
3457
{
3325
3458
  return cStringLength_u((GSStr)self, encoding);
3326
3459
}
3353
3486
  return obj;
3354
3487
}
3355
3488
 
3356
 
- (NSRange) rangeOfComposedCharacterSequenceAtIndex: (unsigned)anIndex
 
3489
- (NSRange) rangeOfComposedCharacterSequenceAtIndex: (NSUInteger)anIndex
3357
3490
{
3358
3491
  return rangeOfSequence_u((GSStr)self, anIndex);
3359
3492
}
3360
3493
 
3361
3494
- (NSRange) rangeOfCharacterFromSet: (NSCharacterSet*)aSet
3362
 
                            options: (unsigned)mask
 
3495
                            options: (NSUInteger)mask
3363
3496
                              range: (NSRange)aRange
3364
3497
{
3365
3498
  GS_RANGE_CHECK(aRange, _count);
3367
3500
}
3368
3501
 
3369
3502
- (NSRange) rangeOfString: (NSString*)aString
3370
 
                  options: (unsigned)mask
 
3503
                  options: (NSUInteger)mask
3371
3504
                    range: (NSRange)aRange
3372
3505
{
3373
3506
  GS_RANGE_CHECK(aRange, _count);
3400
3533
}
3401
3534
 
3402
3535
// private method for Unicode level 3 implementation
3403
 
- (int) _baseLength
 
3536
- (NSInteger) _baseLength
3404
3537
{
3405
3538
  unsigned int count = 0;
3406
3539
  unsigned int blen = 0;
3417
3550
*/
3418
3551
- (id) copyWithZone: (NSZone*)z
3419
3552
{
3420
 
  if (!_flags.free || NSShouldRetainWithZone(self, z) == NO)
 
3553
  if (!_flags.owned || NSShouldRetainWithZone(self, z) == NO)
3421
3554
    {
3422
 
      struct {
3423
 
        @defs(GSUnicodeInlineString)
3424
 
      } *o;
 
3555
      GSUnicodeInlineString *o;
3425
3556
 
3426
3557
      o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass,
3427
3558
        _count * sizeof(unichar), z);
3428
 
      o->_contents.u = (unichar*)&o[1];
 
3559
      o->_contents.u = (unichar*)
 
3560
        (((void*)o)+class_getInstanceSize(GSUnicodeInlineStringClass));
3429
3561
      o->_count = _count;
3430
3562
      memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar));
3431
3563
      o->_flags.wide = 1;
3432
 
      o->_flags.free = 1;       // Ignored on dealloc, but means we own buffer
 
3564
      o->_flags.owned = 1;      // Ignored on dealloc, but means we own buffer
3433
3565
      return (id)o;
3434
3566
    }
3435
3567
  else
3445
3577
@implementation GSUnicodeBufferString
3446
3578
- (void) dealloc
3447
3579
{
3448
 
  if (_flags.free && _contents.u != 0)
 
3580
  if (_contents.u != 0)
3449
3581
    {
3450
 
      NSZoneFree(NSZoneFromPointer(_contents.u), _contents.u);
 
3582
      if (_flags.owned)
 
3583
        {
 
3584
          NSZoneFree(NSZoneFromPointer(_contents.u), _contents.u);
 
3585
        }
3451
3586
      _contents.u = 0;
3452
3587
    }
3453
 
  NSDeallocateObject(self);
3454
 
  GSNOSUPERDEALLOC;
 
3588
  [super dealloc];
3455
3589
}
3456
3590
@end
3457
3591
 
3458
3592
 
3459
3593
 
3460
3594
@implementation GSUnicodeInlineString
3461
 
- (void) dealloc
3462
 
{
3463
 
  NSDeallocateObject(self);
3464
 
  GSNOSUPERDEALLOC;
3465
 
}
3466
3595
@end
3467
3596
 
3468
3597
 
3474
3603
 */
3475
3604
- (id) copyWithZone: (NSZone*)z
3476
3605
{
3477
 
  struct {
3478
 
    @defs(GSUnicodeInlineString)
3479
 
  } *o;
 
3606
  GSUnicodeInlineString *o;
3480
3607
 
3481
3608
  o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass,
3482
3609
    _count * sizeof(unichar), z);
3483
 
  o->_contents.u = (unichar*)&o[1];
 
3610
  o->_contents.u = (unichar*)
 
3611
    (((void*)o)+class_getInstanceSize(GSUnicodeInlineStringClass));
3484
3612
  o->_count = _count;
3485
3613
  memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar));
3486
3614
  o->_flags.wide = 1;
3487
 
  o->_flags.free = 1;   // Ignored on dealloc, but means we own buffer
 
3615
  o->_flags.owned = 1;  // Ignored on dealloc, but means we own buffer
3488
3616
  return (id)o;
3489
3617
}
3490
3618
 
3491
3619
- (void) dealloc
3492
3620
{
3493
3621
  DESTROY(_parent);
3494
 
  NSDeallocateObject(self);
3495
 
  GSNOSUPERDEALLOC;
 
3622
  [super dealloc];
3496
3623
}
3497
3624
@end
3498
3625
 
3511
3638
+ (void) initialize
3512
3639
{
3513
3640
  setup();
 
3641
  GSObjCAddClassBehavior(self, [GSString class]);
3514
3642
}
3515
3643
 
3516
3644
- (void) appendFormat: (NSString*)format, ...
3531
3659
  len = [format length];
3532
3660
  if (len >= 1024)
3533
3661
    {
3534
 
      fmt = objc_malloc((len+1)*sizeof(unichar));
 
3662
      fmt = NSZoneMalloc(NSDefaultMallocZone(), (len+1)*sizeof(unichar));
3535
3663
    }
3536
3664
  [format getCharacters: fmt];
3537
3665
  fmt[len] = '\0';
3545
3673
#if     GS_WITH_GC
3546
3674
      _zone = GSAtomicMallocZone();
3547
3675
#else
3548
 
      _zone = GSObjCZone(self);
 
3676
      _zone = [self zone];
3549
3677
#endif
3550
3678
    }
3551
3679
  GSPrivateFormat((GSStr)self, fmt, ap, nil);
3552
3680
  _flags.hash = 0;      // Invalidate the hash for this string.
3553
3681
  if (fmt != buf)
3554
3682
    {
3555
 
      objc_free(fmt);
 
3683
      NSZoneFree(NSDefaultMallocZone(), fmt);
3556
3684
    }
3557
3685
  va_end(ap);
3558
3686
}
3573
3701
    return canBeConvertedToEncoding_c((GSStr)self, enc);
3574
3702
}
3575
3703
 
3576
 
- (unichar) characterAtIndex: (unsigned int)index
 
3704
- (unichar) characterAtIndex: (NSUInteger)index
3577
3705
{
3578
3706
  if (_flags.wide == 1)
3579
3707
    return characterAtIndex_u((GSStr)self, index);
3582
3710
}
3583
3711
 
3584
3712
- (NSComparisonResult) compare: (NSString*)aString
3585
 
                       options: (unsigned int)mask
 
3713
                       options: (NSUInteger)mask
3586
3714
                         range: (NSRange)aRange
3587
3715
{
3588
3716
  GS_RANGE_CHECK(aRange, _count);
3604
3732
{
3605
3733
  if (_flags.wide == 1)
3606
3734
    {
3607
 
      struct {
3608
 
        @defs(GSUnicodeInlineString)
3609
 
      } *o;
 
3735
      GSUnicodeInlineString *o;
3610
3736
 
3611
3737
      o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass,
3612
3738
        _count * sizeof(unichar), z);
3613
 
      o->_contents.u = (unichar*)&o[1];
 
3739
      o->_contents.u = (unichar*)
 
3740
        (((void*)o)+class_getInstanceSize(GSUnicodeInlineStringClass));
3614
3741
      o->_count = _count;
3615
3742
      memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar));
3616
3743
      o->_flags.wide = 1;
3617
 
      o->_flags.free = 1;       // Ignored on dealloc, but means we own buffer
 
3744
      o->_flags.owned = 1;      // Ignored on dealloc, but means we own buffer
3618
3745
      return (id)o;
3619
3746
    }
3620
3747
  else
3621
3748
    {
3622
 
      struct {
3623
 
        @defs(GSCInlineString)
3624
 
      } *o;
 
3749
      GSCInlineString *o;
3625
3750
 
3626
3751
      o = (typeof(o))NSAllocateObject(GSCInlineStringClass, _count, z);
3627
 
      o->_contents.c = (unsigned char*)&o[1];
 
3752
      o->_contents.c = (unsigned char*)
 
3753
        (((void*)o)+class_getInstanceSize(GSCInlineStringClass));
3628
3754
      o->_count = _count;
3629
3755
      memcpy(o->_contents.c, _contents.c, _count);
3630
3756
      o->_flags.wide = 0;
3631
 
      o->_flags.free = 1;       // Ignored on dealloc, but means we own buffer
 
3757
      o->_flags.owned = 1;      // Ignored on dealloc, but means we own buffer
3632
3758
      return (id)o;
3633
3759
    }
3634
3760
}
3649
3775
    return cString_c((GSStr)self, encoding);
3650
3776
}
3651
3777
 
3652
 
- (unsigned int) cStringLength
 
3778
- (NSUInteger) cStringLength
3653
3779
{
3654
3780
  if (_flags.wide == 1)
3655
3781
    return cStringLength_u((GSStr)self, externalEncoding);
3668
3794
 
3669
3795
- (void) dealloc
3670
3796
{
3671
 
NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException);
3672
3797
  if (_contents.c != 0)
3673
3798
    {
 
3799
NSAssert(_flags.owned == 1 && _zone != 0, NSInternalInconsistencyException);
3674
3800
      NSZoneFree(self->_zone, self->_contents.c);
3675
3801
      self->_contents.c = 0;
3676
3802
      self->_zone = 0;
3677
3803
    }
3678
 
  NSDeallocateObject(self);
3679
 
  GSNOSUPERDEALLOC;
 
3804
  [super dealloc];
3680
3805
}
3681
3806
 
3682
3807
- (void) deleteCharactersInRange: (NSRange)range
3775
3900
}
3776
3901
 
3777
3902
- (void) getCString: (char*)buffer
3778
 
          maxLength: (unsigned int)maxLength
 
3903
          maxLength: (NSUInteger)maxLength
3779
3904
{
3780
3905
  if (_flags.wide == 1)
3781
3906
    getCString_u((GSStr)self, buffer, maxLength, (NSRange){0, _count}, 0);
3784
3909
}
3785
3910
 
3786
3911
- (BOOL) getCString: (char*)buffer
3787
 
          maxLength: (unsigned int)maxLength
 
3912
          maxLength: (NSUInteger)maxLength
3788
3913
           encoding: (NSStringEncoding)encoding
3789
3914
{
3790
3915
  if (_flags.wide == 1)
3794
3919
}
3795
3920
 
3796
3921
- (void) getCString: (char*)buffer
3797
 
          maxLength: (unsigned int)maxLength
 
3922
          maxLength: (NSUInteger)maxLength
3798
3923
              range: (NSRange)aRange
3799
3924
     remainingRange: (NSRange*)leftoverRange
3800
3925
{
3809
3934
    }
3810
3935
}
3811
3936
 
3812
 
- (unsigned) hash
3813
 
{
3814
 
  if (self->_flags.hash == 0)
3815
 
    {
3816
 
      self->_flags.hash = (*hashImp)((id)self, hashSel);
3817
 
    }
3818
 
  return self->_flags.hash;
3819
 
}
3820
 
 
3821
3937
- (id) init
3822
3938
{
3823
3939
  return [self initWithCapacity: 0];
3824
3940
}
3825
3941
 
3826
3942
- (id) initWithBytes: (const void*)bytes
3827
 
              length: (unsigned int)length
 
3943
              length: (NSUInteger)length
3828
3944
            encoding: (NSStringEncoding)encoding
3829
3945
{
3830
3946
  unsigned char *chars = 0;
3832
3948
  BOOL          isLatin1 = NO;
3833
3949
  BOOL          shouldFree = NO;
3834
3950
 
3835
 
  _flags.free = YES;
 
3951
  _flags.owned = YES;
3836
3952
#if     GS_WITH_GC
3837
3953
  _zone = GSAtomicMallocZone();
3838
3954
#else
3839
 
  _zone = GSObjCZone(self);
 
3955
  _zone = [self zone];
3840
3956
#endif
3841
3957
 
3842
3958
  if (length > 0)
3875
3991
            {
3876
3992
              if (encoding == NSASCIIStringEncoding)
3877
3993
                {
3878
 
                  RELEASE(self);
 
3994
                  DESTROY(self);
3879
3995
                  if (shouldFree == YES)
3880
3996
                    {
3881
3997
                      NSZoneFree(NSZoneFromPointer(chars), chars);
3923
4039
      if (GSToUnicode(&u, &l, (unsigned char*)chars, length, encoding,
3924
4040
        _zone, 0) == NO)
3925
4041
        {
3926
 
          RELEASE(self);
 
4042
          DESTROY(self);
3927
4043
          if (shouldFree == YES)
3928
4044
            {
3929
4045
              NSZoneFree(NSZoneFromPointer(chars), chars);
3980
4096
}
3981
4097
 
3982
4098
- (id) initWithBytesNoCopy: (void*)bytes
3983
 
                    length: (unsigned int)length
 
4099
                    length: (NSUInteger)length
3984
4100
                  encoding: (NSStringEncoding)encoding
3985
4101
              freeWhenDone: (BOOL)flag
3986
4102
{
3994
4110
  return self;
3995
4111
}
3996
4112
 
3997
 
- (id) initWithCapacity: (unsigned)capacity
 
4113
- (id) initWithCapacity: (NSUInteger)capacity
3998
4114
{
3999
4115
  if (capacity < 2)
4000
4116
    {
4005
4121
#if     GS_WITH_GC
4006
4122
  _zone = GSAtomicMallocZone();
4007
4123
#else
4008
 
  _zone = GSObjCZone(self);
 
4124
  _zone = [self zone];
4009
4125
#endif
4010
4126
  _contents.c = NSZoneMalloc(_zone, capacity + 1);
4011
4127
  _flags.wide = 0;
4012
 
  _flags.free = 1;
 
4128
  _flags.owned = 1;
4013
4129
  return self;
4014
4130
}
4015
4131
 
4016
4132
- (id) initWithCharactersNoCopy: (unichar*)chars
4017
 
                         length: (unsigned int)length
 
4133
                         length: (NSUInteger)length
4018
4134
                   freeWhenDone: (BOOL)flag
4019
4135
{
4020
4136
  return [self initWithBytesNoCopy: (void*)chars
4024
4140
}
4025
4141
 
4026
4142
- (id) initWithCStringNoCopy: (char*)chars
4027
 
                      length: (unsigned int)length
 
4143
                      length: (NSUInteger)length
4028
4144
                freeWhenDone: (BOOL)flag
4029
4145
{
4030
4146
  return [self initWithBytesNoCopy: (void*)chars
4050
4166
  len = [format length];
4051
4167
  if (len >= 1024)
4052
4168
    {
4053
 
      fmt = objc_malloc((len+1)*sizeof(unichar));
 
4169
      fmt = NSZoneMalloc(NSDefaultMallocZone(), (len+1)*sizeof(unichar));
4054
4170
    }
4055
4171
  [format getCharacters: fmt];
4056
4172
  fmt[len] = '\0';
4058
4174
  GSPrivateFormat((GSStr)self, fmt, argList, locale);
4059
4175
  if (fmt != fbuf)
4060
4176
    {
4061
 
      objc_free(fmt);
 
4177
      NSZoneFree(NSDefaultMallocZone(), fmt);
4062
4178
    }
4063
4179
  return self;
4064
4180
}
4065
4181
 
4066
 
- (int) intValue
 
4182
- (NSInteger) intValue
4067
4183
{
4068
4184
  if (_flags.wide == 1)
4069
4185
    return intValue_u((GSStr)self);
4087
4203
    return isEqual_c((GSStr)self, anObject);
4088
4204
}
4089
4205
 
4090
 
- (unsigned int) length
 
4206
- (NSUInteger) length
4091
4207
{
4092
4208
  return _count;
4093
4209
}
4094
4210
 
4095
 
- (unsigned int) lengthOfBytesUsingEncoding: (NSStringEncoding)encoding
 
4211
- (NSUInteger) lengthOfBytesUsingEncoding: (NSStringEncoding)encoding
4096
4212
{
4097
4213
  if (_flags.wide == 1)
4098
4214
    return cStringLength_u((GSStr)self, encoding);
4110
4226
 
4111
4227
- (id) makeImmutableCopyOnFail: (BOOL)force
4112
4228
{
4113
 
NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException);
 
4229
NSAssert(_flags.owned == 1 && _zone != 0, NSInternalInconsistencyException);
4114
4230
#ifndef NDEBUG
4115
4231
  GSDebugAllocationRemove(isa, self);
4116
4232
#endif
4163
4279
  return obj;
4164
4280
}
4165
4281
 
4166
 
- (NSRange) rangeOfComposedCharacterSequenceAtIndex: (unsigned)anIndex
 
4282
- (NSRange) rangeOfComposedCharacterSequenceAtIndex: (NSUInteger)anIndex
4167
4283
{
4168
4284
  if (_flags.wide == 1)
4169
4285
    return rangeOfSequence_u((GSStr)self, anIndex);
4172
4288
}
4173
4289
 
4174
4290
- (NSRange) rangeOfCharacterFromSet: (NSCharacterSet*)aSet
4175
 
                            options: (unsigned)mask
 
4291
                            options: (NSUInteger)mask
4176
4292
                              range: (NSRange)aRange
4177
4293
{
4178
4294
  GS_RANGE_CHECK(aRange, _count);
4183
4299
}
4184
4300
 
4185
4301
- (NSRange) rangeOfString: (NSString*)aString
4186
 
                  options: (unsigned)mask
 
4302
                  options: (NSUInteger)mask
4187
4303
                    range: (NSRange)aRange
4188
4304
{
4189
4305
  GS_RANGE_CHECK(aRange, _count);
4239
4355
    }
4240
4356
  else if (offset > 0)
4241
4357
    {
4242
 
      makeHole((GSStr)self, NSMaxRange(aRange), (unsigned int)offset);
 
4358
      makeHole((GSStr)self, NSMaxRange(aRange), (NSUInteger)offset);
4243
4359
    }
4244
4360
 
4245
4361
  if (length > 0)
4322
4438
  other = transmute((GSStr)self, aString);
4323
4439
  if (_count < len)
4324
4440
    {
4325
 
      makeHole((GSStr)self, _count, (unsigned int)(len - _count));
 
4441
      makeHole((GSStr)self, _count, (NSUInteger)(len - _count));
4326
4442
    }
4327
4443
  else
4328
4444
    {
4395
4511
    }
4396
4512
  if (_flags.wide == 1)
4397
4513
    {
4398
 
      struct {
4399
 
        @defs(GSUnicodeInlineString)
4400
 
      } *o;
 
4514
      GSUnicodeInlineString *o;
4401
4515
 
4402
4516
      o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass,
4403
4517
        aRange.length * sizeof(unichar), NSDefaultMallocZone());
4404
 
      o->_contents.u = (unichar*)&o[1];
 
4518
      o->_contents.u = (unichar*)
 
4519
        (((void*)o)+class_getInstanceSize(GSUnicodeInlineStringClass));
4405
4520
      o->_count = aRange.length;
4406
4521
      memcpy(o->_contents.u, _contents.u + aRange.location,
4407
4522
        aRange.length * sizeof(unichar));
4408
4523
      o->_flags.wide = 1;
4409
 
      o->_flags.free = 1;       // Ignored on dealloc, but means we own buffer
 
4524
      o->_flags.owned = 1;      // Ignored on dealloc, but means we own buffer
4410
4525
      return AUTORELEASE((id)o);
4411
4526
    }
4412
4527
  else
4413
4528
    {
4414
 
      struct {
4415
 
        @defs(GSCInlineString)
4416
 
      } *o;
 
4529
      GSCInlineString *o;
4417
4530
 
4418
4531
      o = (typeof(o))NSAllocateObject(GSCInlineStringClass,
4419
4532
        aRange.length, NSDefaultMallocZone());
4420
 
      o->_contents.c = (unsigned char*)&o[1];
 
4533
      o->_contents.c = (unsigned char*)
 
4534
        (((void*)o)+class_getInstanceSize(GSCInlineStringClass));
4421
4535
      o->_count = aRange.length;
4422
4536
      memcpy(o->_contents.c, _contents.c + aRange.location, aRange.length);
4423
4537
      o->_flags.wide = 0;
4424
 
      o->_flags.free = 1;       // Ignored on dealloc, but means we own buffer
 
4538
      o->_flags.owned = 1;      // Ignored on dealloc, but means we own buffer
4425
4539
      return AUTORELEASE((id)o);
4426
4540
    }
4427
4541
}
4436
4550
    }
4437
4551
  if (_flags.wide == 1)
4438
4552
    {
4439
 
      struct {
4440
 
        @defs(GSUnicodeInlineString)
4441
 
      } *o;
 
4553
      GSUnicodeInlineString *o;
4442
4554
 
4443
4555
      o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass,
4444
4556
        aRange.length * sizeof(unichar), NSDefaultMallocZone());
4445
 
      o->_contents.u = (unichar*)&o[1];
 
4557
      o->_contents.u = (unichar*)
 
4558
        (((void*)o)+class_getInstanceSize(GSUnicodeInlineStringClass));
4446
4559
      o->_count = aRange.length;
4447
4560
      memcpy(o->_contents.u, _contents.u + aRange.location,
4448
4561
        aRange.length * sizeof(unichar));
4449
4562
      o->_flags.wide = 1;
4450
 
      o->_flags.free = 1;       // Ignored on dealloc, but means we own buffer
 
4563
      o->_flags.owned = 1;      // Ignored on dealloc, but means we own buffer
4451
4564
      return AUTORELEASE((id)o);
4452
4565
    }
4453
4566
  else
4454
4567
    {
4455
 
      struct {
4456
 
        @defs(GSCInlineString)
4457
 
      } *o;
 
4568
      GSCInlineString *o;
4458
4569
 
4459
4570
      o = (typeof(o))NSAllocateObject(GSCInlineStringClass,
4460
4571
        aRange.length, NSDefaultMallocZone());
4461
 
      o->_contents.c = (unsigned char*)&o[1];
 
4572
      o->_contents.c = (unsigned char*)
 
4573
        (((void*)o)+class_getInstanceSize(GSCInlineStringClass));
4462
4574
      o->_count = aRange.length;
4463
4575
      memcpy(o->_contents.c, _contents.c + aRange.location, aRange.length);
4464
4576
      o->_flags.wide = 0;
4465
 
      o->_flags.free = 1;       // Ignored on dealloc, but means we own buffer
 
4577
      o->_flags.owned = 1;      // Ignored on dealloc, but means we own buffer
4466
4578
      return AUTORELEASE((id)o);
4467
4579
    }
4468
4580
}
4469
4581
 
4470
4582
// private method for Unicode level 3 implementation
4471
 
- (int) _baseLength
 
4583
- (NSInteger) _baseLength
4472
4584
{
4473
4585
  if (_flags.wide == 1)
4474
4586
    {
4488
4600
 
4489
4601
 
4490
4602
 
4491
 
@interface      NSImmutableString: NSString
4492
 
{
4493
 
  id    _parent;
4494
 
}
4495
 
- (id) initWithString: (NSString*)parent;
4496
 
@end
4497
 
 
4498
 
@interface      GSImmutableString: NSImmutableString
4499
 
@end
4500
 
 
4501
 
@implementation NSImmutableString
4502
 
 
4503
 
- (BOOL) canBeConvertedToEncoding: (NSStringEncoding)enc
4504
 
{
4505
 
  return [_parent canBeConvertedToEncoding: enc];
4506
 
}
4507
 
 
4508
 
- (unichar) characterAtIndex: (unsigned int)index
4509
 
{
4510
 
  return [_parent characterAtIndex: index];
4511
 
}
4512
 
 
4513
 
- (NSComparisonResult) compare: (NSString*)aString
4514
 
                       options: (unsigned int)mask
4515
 
                         range: (NSRange)aRange
4516
 
{
4517
 
  return [_parent compare: aString options: mask range: aRange];
4518
 
}
4519
 
 
4520
 
- (const char *) cString
4521
 
{
4522
 
  return [_parent cString];
4523
 
}
4524
 
 
4525
 
- (const char *) cStringUsingEncoding
4526
 
{
4527
 
  return [_parent cStringUsingEncoding];
4528
 
}
4529
 
 
4530
 
- (unsigned int) cStringLength
4531
 
{
4532
 
  return [_parent cStringLength];
4533
 
}
4534
 
 
4535
 
- (NSData*) dataUsingEncoding: (NSStringEncoding)encoding
4536
 
         allowLossyConversion: (BOOL)flag
4537
 
{
4538
 
  return [_parent dataUsingEncoding: encoding allowLossyConversion: flag];
4539
 
}
4540
 
 
4541
 
- (void) dealloc
4542
 
{
4543
 
  RELEASE(_parent);
4544
 
  [super dealloc];
4545
 
}
4546
 
 
4547
 
- (id) copyWithZone: (NSZone*)z
4548
 
{
4549
 
  return [_parent copyWithZone: z];
4550
 
}
4551
 
 
4552
 
- (id) mutableCopy
4553
 
{
4554
 
  return [_parent mutableCopy];
4555
 
}
4556
 
 
4557
 
- (id) mutableCopyWithZone: (NSZone*)z
4558
 
{
4559
 
  return [_parent mutableCopyWithZone: z];
4560
 
}
4561
 
 
4562
 
- (void) encodeWithCoder: (NSCoder*)aCoder
4563
 
{
4564
 
  [_parent encodeWithCoder: aCoder];
4565
 
}
4566
 
 
4567
 
- (NSStringEncoding) fastestEncoding
4568
 
{
4569
 
  return [_parent fastestEncoding];
4570
 
}
4571
 
 
4572
 
- (void) getCharacters: (unichar*)buffer
4573
 
{
4574
 
  [_parent getCharacters: buffer];
4575
 
}
4576
 
 
4577
 
- (void) getCharacters: (unichar*)buffer range: (NSRange)aRange
4578
 
{
4579
 
  [_parent getCharacters: buffer range: aRange];
4580
 
}
4581
 
 
4582
 
- (void) getCString: (char*)buffer
4583
 
{
4584
 
  [_parent getCString: buffer];
4585
 
}
4586
 
 
4587
 
- (void) getCString: (char*)buffer
4588
 
          maxLength: (unsigned int)maxLength
4589
 
{
4590
 
  [_parent getCString: buffer maxLength: maxLength];
4591
 
}
4592
 
 
4593
 
- (BOOL) getCString: (char*)buffer
4594
 
          maxLength: (unsigned int)maxLength
4595
 
           encoding: (NSStringEncoding)encoding
4596
 
{
4597
 
  return [_parent getCString: buffer maxLength: maxLength encoding: encoding];
4598
 
}
4599
 
 
4600
 
- (void) getCString: (char*)buffer
4601
 
          maxLength: (unsigned int)maxLength
4602
 
              range: (NSRange)aRange
4603
 
     remainingRange: (NSRange*)leftoverRange
4604
 
{
4605
 
  [_parent getCString: buffer
4606
 
            maxLength: maxLength
4607
 
                range: aRange
4608
 
       remainingRange: leftoverRange];
4609
 
}
4610
 
 
4611
 
- (unsigned) hash
4612
 
{
4613
 
  return [_parent hash];
4614
 
}
4615
 
 
4616
 
- (id) initWithString: (NSString*)parent
4617
 
{
4618
 
  _parent = RETAIN(parent);
4619
 
  return self;
4620
 
}
4621
 
 
4622
 
- (BOOL) isEqual: (id)anObject
4623
 
{
4624
 
  return [_parent isEqual: anObject];
4625
 
}
4626
 
 
4627
 
- (BOOL) isEqualToString: (NSString*)anObject
4628
 
{
4629
 
  return [_parent isEqualToString: anObject];
4630
 
}
4631
 
 
4632
 
- (unsigned int) length
4633
 
{
4634
 
  return [_parent length];
4635
 
}
4636
 
 
4637
 
- (unsigned int) lengthOfBytesUsingEncoding
4638
 
{
4639
 
  return [_parent lengthOfBytesUsingEncoding];
4640
 
}
4641
 
 
4642
 
- (const char*) lossyCString
4643
 
{
4644
 
  return [_parent lossyCString];
4645
 
}
4646
 
 
4647
 
- (unsigned int) maximumLengthOfBytesUsingEncoding
4648
 
{
4649
 
  return [_parent maximumLengthOfBytesUsingEncoding];
4650
 
}
4651
 
 
4652
 
- (NSRange) rangeOfComposedCharacterSequenceAtIndex: (unsigned)anIndex
4653
 
{
4654
 
  return [_parent rangeOfComposedCharacterSequenceAtIndex: anIndex];
4655
 
}
4656
 
 
4657
 
- (NSRange) rangeOfCharacterFromSet: (NSCharacterSet*)aSet
4658
 
                            options: (unsigned)mask
4659
 
                              range: (NSRange)aRange
4660
 
{
4661
 
  GS_RANGE_CHECK(aRange, ((GSStr)_parent)->_count);
4662
 
  return [_parent rangeOfCharacterFromSet: aSet options: mask range: aRange];
4663
 
}
4664
 
 
4665
 
- (NSRange) rangeOfString: (NSString*)aString
4666
 
                  options: (unsigned)mask
4667
 
                    range: (NSRange)aRange
4668
 
{
4669
 
  GS_RANGE_CHECK(aRange, ((GSStr)_parent)->_count);
4670
 
  if (aString == nil)
4671
 
    [NSException raise: NSInvalidArgumentException
4672
 
                format: @"[%@ -%@] nil string argument",
4673
 
      NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
4674
 
  if (GSObjCIsInstance(aString) == NO)
4675
 
    [NSException raise: NSInvalidArgumentException
4676
 
                format: @"[%@ -%@] not a string argument",
4677
 
      NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
4678
 
  return [_parent rangeOfString: aString options: mask range: aRange];
4679
 
}
4680
 
 
4681
 
- (NSStringEncoding) smallestEncoding
4682
 
{
4683
 
  return [_parent smallestEncoding];
4684
 
}
4685
 
 
4686
 
@end
4687
 
 
4688
 
 
4689
 
@implementation GSImmutableString
4690
 
 
4691
 
+ (void) initialize
4692
 
{
4693
 
  setup();
4694
 
}
4695
 
 
4696
 
- (BOOL) canBeConvertedToEncoding: (NSStringEncoding)enc
4697
 
{
4698
 
  if (((GSStr)_parent)->_flags.wide == 1)
4699
 
    return canBeConvertedToEncoding_u((GSStr)_parent, enc);
4700
 
  else
4701
 
    return canBeConvertedToEncoding_c((GSStr)_parent, enc);
4702
 
}
4703
 
 
4704
 
- (unichar) characterAtIndex: (unsigned int)index
4705
 
{
4706
 
  if (((GSStr)_parent)->_flags.wide == 1)
4707
 
    return characterAtIndex_u((GSStr)_parent, index);
4708
 
  else
4709
 
    return characterAtIndex_c((GSStr)_parent, index);
4710
 
}
4711
 
 
4712
 
- (NSComparisonResult) compare: (NSString*)aString
4713
 
                       options: (unsigned int)mask
4714
 
                         range: (NSRange)aRange
4715
 
{
4716
 
  GS_RANGE_CHECK(aRange, ((GSStr)_parent)->_count);
4717
 
  if (aString == nil)
4718
 
    [NSException raise: NSInvalidArgumentException
4719
 
                format: @"[%@ -%@] nil string argument",
4720
 
      NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
4721
 
  if (GSObjCIsInstance(aString) == NO)
4722
 
    [NSException raise: NSInvalidArgumentException
4723
 
                format: @"[%@ -%@] not a string argument",
4724
 
      NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
4725
 
  if (((GSStr)_parent)->_flags.wide == 1)
4726
 
    return compare_u((GSStr)_parent, aString, mask, aRange);
4727
 
  else
4728
 
    return compare_c((GSStr)_parent, aString, mask, aRange);
4729
 
}
4730
 
 
4731
 
- (const char *) cString
4732
 
{
4733
 
  if (((GSStr)_parent)->_flags.wide == 1)
4734
 
    return cString_u((GSStr)_parent, externalEncoding);
4735
 
  else
4736
 
    return cString_c((GSStr)_parent, externalEncoding);
4737
 
}
4738
 
 
4739
 
- (const char *) cStringUsingEncoding: (NSStringEncoding)encoding
4740
 
{
4741
 
  if (((GSStr)_parent)->_flags.wide == 1)
4742
 
    return cString_u((GSStr)_parent, encoding);
4743
 
  else
4744
 
    return cString_c((GSStr)_parent, encoding);
4745
 
}
4746
 
 
4747
 
- (unsigned int) cStringLength
4748
 
{
4749
 
  if (((GSStr)_parent)->_flags.wide == 1)
4750
 
    return cStringLength_u((GSStr)_parent, externalEncoding);
4751
 
  else
4752
 
    return cStringLength_c((GSStr)_parent, externalEncoding);
4753
 
}
4754
 
 
4755
 
- (NSData*) dataUsingEncoding: (NSStringEncoding)encoding
4756
 
         allowLossyConversion: (BOOL)flag
4757
 
{
4758
 
  if (((GSStr)_parent)->_flags.wide == 1)
4759
 
    return dataUsingEncoding_u((GSStr)_parent, encoding, flag);
4760
 
  else
4761
 
    return dataUsingEncoding_c((GSStr)_parent, encoding, flag);
4762
 
}
4763
 
 
4764
 
- (void) encodeWithCoder: (NSCoder*)aCoder
4765
 
{
4766
 
  [_parent encodeWithCoder: aCoder];
4767
 
}
4768
 
 
4769
 
- (NSStringEncoding) fastestEncoding
4770
 
{
4771
 
  if (((GSStr)_parent)->_flags.wide == 1)
4772
 
    return NSUnicodeStringEncoding;
4773
 
  else
4774
 
    return internalEncoding;
4775
 
}
4776
 
 
4777
 
- (void) getCharacters: (unichar*)buffer
4778
 
{
4779
 
  if (((GSStr)_parent)->_flags.wide == 1)
4780
 
    {
4781
 
      getCharacters_u((GSStr)_parent, buffer,
4782
 
        (NSRange){0, ((GSStr)_parent)->_count});
4783
 
    }
4784
 
  else
4785
 
    {
4786
 
      getCharacters_c((GSStr)_parent, buffer,
4787
 
        (NSRange){0, ((GSStr)_parent)->_count});
4788
 
    }
4789
 
}
4790
 
 
4791
 
- (void) getCharacters: (unichar*)buffer range: (NSRange)aRange
4792
 
{
4793
 
  GS_RANGE_CHECK(aRange, ((GSStr)_parent)->_count);
4794
 
  if (((GSStr)_parent)->_flags.wide == 1)
4795
 
    {
4796
 
      getCharacters_u((GSStr)_parent, buffer, aRange);
4797
 
    }
4798
 
  else
4799
 
    {
4800
 
      getCharacters_c((GSStr)_parent, buffer, aRange);
4801
 
    }
4802
 
}
4803
 
 
4804
 
- (unsigned) hash
4805
 
{
4806
 
  if (((GSStr)_parent)->_flags.hash == 0)
4807
 
    {
4808
 
      ((GSStr)_parent)->_flags.hash = (*hashImp)((id)_parent, hashSel);
4809
 
    }
4810
 
  return ((GSStr)_parent)->_flags.hash;
4811
 
}
4812
 
 
4813
 
- (BOOL) isEqual: (id)anObject
4814
 
{
4815
 
  if (((GSStr)_parent)->_flags.wide == 1)
4816
 
    return isEqual_u((GSStr)_parent, anObject);
4817
 
  else
4818
 
    return isEqual_c((GSStr)_parent, anObject);
4819
 
}
4820
 
 
4821
 
- (BOOL) isEqualToString: (NSString*)anObject
4822
 
{
4823
 
  if (((GSStr)_parent)->_flags.wide == 1)
4824
 
    return isEqual_u((GSStr)_parent, anObject);
4825
 
  else
4826
 
    return isEqual_c((GSStr)_parent, anObject);
4827
 
}
4828
 
 
4829
 
- (unsigned int) length
4830
 
{
4831
 
  return ((GSStr)_parent)->_count;
4832
 
}
4833
 
 
4834
 
- (unsigned int) lengthOfBytesUsingEncoding: (NSStringEncoding)encoding
4835
 
{
4836
 
  if (((GSStr)_parent)->_flags.wide == 1)
4837
 
    return cStringLength_u((GSStr)_parent, encoding);
4838
 
  else
4839
 
    return cStringLength_c((GSStr)_parent, encoding);
4840
 
}
4841
 
 
4842
 
- (const char*) lossyCString
4843
 
{
4844
 
  if (((GSStr)_parent)->_flags.wide == 1)
4845
 
    return lossyCString_u((GSStr)_parent);
4846
 
  else
4847
 
    return lossyCString_c((GSStr)_parent);
4848
 
}
4849
 
 
4850
 
- (unsigned int) maximumLengthOfBytesUsingEncoding
4851
 
{
4852
 
  return [_parent maximumLengthOfBytesUsingEncoding];
4853
 
}
4854
 
 
4855
 
- (NSRange) rangeOfComposedCharacterSequenceAtIndex: (unsigned)anIndex
4856
 
{
4857
 
  if (((GSStr)_parent)->_flags.wide == 1)
4858
 
    return rangeOfSequence_u((GSStr)_parent, anIndex);
4859
 
  else
4860
 
    return rangeOfSequence_c((GSStr)_parent, anIndex);
4861
 
}
4862
 
 
4863
 
- (NSRange) rangeOfCharacterFromSet: (NSCharacterSet*)aSet
4864
 
                            options: (unsigned)mask
4865
 
                              range: (NSRange)aRange
4866
 
{
4867
 
  GS_RANGE_CHECK(aRange, ((GSStr)_parent)->_count);
4868
 
  if (((GSStr)_parent)->_flags.wide == 1)
4869
 
    return rangeOfCharacter_u((GSStr)_parent, aSet, mask, aRange);
4870
 
  else
4871
 
    return rangeOfCharacter_c((GSStr)_parent, aSet, mask, aRange);
4872
 
}
4873
 
 
4874
 
- (NSRange) rangeOfString: (NSString*)aString
4875
 
                  options: (unsigned)mask
4876
 
                    range: (NSRange)aRange
4877
 
{
4878
 
  GS_RANGE_CHECK(aRange, ((GSStr)_parent)->_count);
4879
 
  if (aString == nil)
4880
 
    [NSException raise: NSInvalidArgumentException
4881
 
                format: @"[%@ -%@] nil string argument",
4882
 
      NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
4883
 
  if (GSObjCIsInstance(aString) == NO)
4884
 
    [NSException raise: NSInvalidArgumentException
4885
 
                format: @"[%@ -%@] not a string argument",
4886
 
      NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
4887
 
  if (((GSStr)_parent)->_flags.wide == 1)
4888
 
    return rangeOfString_u((GSStr)_parent, aString, mask, aRange);
4889
 
  else
4890
 
    return rangeOfString_c((GSStr)_parent, aString, mask, aRange);
4891
 
}
4892
 
 
4893
 
- (NSStringEncoding) smallestEncoding
4894
 
{
4895
 
  if (((GSStr)_parent)->_flags.wide == 1)
4896
 
    {
4897
 
      return NSUnicodeStringEncoding;
4898
 
    }
4899
 
  else
4900
 
    {
4901
 
      return internalEncoding;
4902
 
    }
4903
 
}
4904
 
 
4905
 
@end
4906
 
 
4907
 
 
4908
 
 
4909
4603
/**
4910
4604
 * <p>The NXConstantString class is used by the compiler for constant
4911
4605
 * strings, as such its ivar layout is determined by the compiler
4932
4626
#define _self   ((GSStr)self)
4933
4627
 
4934
4628
- (id) initWithBytes: (const void*)bytes
4935
 
              length: (unsigned int)length
 
4629
              length: (NSUInteger)length
4936
4630
            encoding: (NSStringEncoding)encoding
4937
4631
{
4938
4632
  [NSException raise: NSGenericException
4941
4635
}
4942
4636
 
4943
4637
- (id) initWithBytesNoCopy: (void*)bytes
4944
 
                    length: (unsigned int)length
 
4638
                    length: (NSUInteger)length
4945
4639
                  encoding: (NSStringEncoding)encoding
4946
4640
              freeWhenDone: (BOOL)flag
4947
4641
{
4995
4689
  return NSASCIIStringEncoding;
4996
4690
}
4997
4691
 
4998
 
 
4999
4692
/*
5000
4693
 * Return a 28-bit hash value for the string contents - this
5001
4694
 * MUST match the algorithm used by the NSString base class.
5002
4695
 */
5003
 
- (unsigned) hash
 
4696
- (NSUInteger) hash
5004
4697
{
5005
4698
  unsigned      ret = 0;
5006
4699
  unsigned      len = _self->_count;
5007
4700
 
5008
4701
  if (len > 0)
5009
4702
    {
5010
 
      const unsigned char       *p;
5011
 
      unsigned                  char_count = 0;
 
4703
      register const unsigned char      *p;
 
4704
      register unsigned                 index = 0;
5012
4705
 
5013
4706
      p = _self->_contents.c;
5014
 
      while (char_count++ < len)
5015
 
        {
5016
 
          unichar       u = *p++;
5017
 
 
5018
 
          if (u > 127 && internalEncoding != NSISOLatin1StringEncoding)
5019
 
            {
5020
 
              unsigned char     c = (unsigned char)u;
5021
 
              unsigned int      s = 1;
5022
 
              unichar           *d = &u;
5023
 
 
5024
 
              GSToUnicode(&d, &s, &c, 1, internalEncoding, 0, 0);
5025
 
            }
5026
 
          ret = (ret << 5) + ret + u;
 
4707
      if (internalEncoding == NSISOLatin1StringEncoding)
 
4708
        {
 
4709
          while (index < len)
 
4710
            {
 
4711
              ret = (ret << 5) + ret + p[index++];
 
4712
            }
 
4713
        }
 
4714
      else
 
4715
        {
 
4716
          while (index < len)
 
4717
            {
 
4718
              unichar   u = p[index++];
 
4719
 
 
4720
              if (u > 127)
 
4721
                {
 
4722
                  unsigned char c = (unsigned char)u;
 
4723
                  unsigned int  s = 1;
 
4724
                  unichar       *d = &u;
 
4725
 
 
4726
                  GSToUnicode(&d, &s, &c, 1, internalEncoding, 0, 0);
 
4727
                }
 
4728
              ret = (ret << 5) + ret + u;
 
4729
            }
5027
4730
        }
5028
4731
 
5029
4732
      /*
5059
4762
    {
5060
4763
      return NO;
5061
4764
    }
5062
 
  c = GSObjCClass(anObject);
 
4765
  c = object_getClass(anObject);
5063
4766
 
5064
4767
  if (GSObjCIsKindOf(c, GSCStringClass) == YES
5065
4768
    || c == NSConstantStringClass
5083
4786
        }
5084
4787
      return NO;
5085
4788
    }
5086
 
  else if (GSObjCIsKindOf(c, NSStringClass))
 
4789
  else if (YES == [anObject isKindOfClass: NSStringClass]) // may be proxy
5087
4790
    {
5088
4791
      return (*equalImp)(self, equalSel, anObject);
5089
4792
    }
5109
4812
    {
5110
4813
      return NO;
5111
4814
    }
5112
 
  c = GSObjCClass(anObject);
 
4815
  c = object_getClass(anObject);
5113
4816
 
5114
4817
  if (GSObjCIsKindOf(c, GSCStringClass) == YES
5115
4818
    || c == NSConstantStringClass
5133
4836
        }
5134
4837
      return NO;
5135
4838
    }
5136
 
  else if (GSObjCIsKindOf(c, NSStringClass))
 
4839
  else if (YES == [anObject isKindOfClass: NSStringClass]) // may be proxy
5137
4840
    {
5138
4841
      return (*equalImp)(self, equalSel, anObject);
5139
4842
    }