~ubuntu-branches/ubuntu/karmic/gnustep-base/karmic

« back to all changes in this revision

Viewing changes to Source/GSeq.h

  • Committer: Bazaar Package Importer
  • Author(s): Eric Heintzmann
  • Date: 2005-04-17 00:14:38 UTC
  • mfrom: (1.2.1 upstream) (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050417001438-enf0y07c9tku85z1
Tags: 1.10.3-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
 *      The second part of the file contains inline function definitions that
33
33
 *      are designed to be modified depending on the defined macros at the
34
34
 *      point where they are included.  This is meant to be included multiple
35
 
 *      times so the same code can be used for NSString, NSGString, and
36
 
 *      NSGCString objects.
 
35
 *      times so the same code can be used for NSString, and subclasses.
37
36
 */
38
37
 
39
38
#ifndef __GSeq_h_GNUSTEP_BASE_INCLUDE
73
72
    GSeqStruct  SEQ = { BUF, LEN, LEN * MAXDEC, 0 }
74
73
 
75
74
/*
76
 
 *      A function to normalize a unicode character sequence.
 
75
 * A function to normalize a unicode character sequence ... produces a
 
76
 * sequence containing composed characters in a well defined order and
 
77
 * with a nul terminator as well as a character count.
77
78
 */
78
79
static inline void GSeq_normalize(GSeq seq)
79
80
{
80
81
  unsigned      count = seq->count;
81
 
  unichar       *source = seq->chars;
82
82
 
83
83
  if (count)
84
84
    {
 
85
      unichar   *source = seq->chars;
85
86
      unichar   target[count*MAXDEC+1];
86
 
      BOOL      notdone = YES;
87
 
 
88
 
      while (notdone)
89
 
        {
90
 
          unichar       *spoint = source;
91
 
          unichar       *tpoint = target;
92
 
 
93
 
          source[count] = (unichar)(0);
94
 
          notdone = NO;
95
 
          do
96
 
            {
97
 
              unichar   *dpoint = uni_is_decomp(*spoint);
98
 
 
99
 
              if (!dpoint)
100
 
                {
101
 
                  *tpoint++ = *spoint;
 
87
      unsigned  base = 0;
 
88
 
 
89
      /*
 
90
       * Pre-scan ... anything with a code under 0x00C0 is not a decomposable
 
91
       * character, so we don't need to expand it.
 
92
       * If there are no decomposable characters or composed sequences, the
 
93
       * sequence is already normalised and we don't need to make any changes.
 
94
       */
 
95
      while (base < count)
 
96
        {
 
97
          if (source[base] >= 0x00C0)
 
98
            {
 
99
              break;
 
100
            }
 
101
          base++;
 
102
        }
 
103
      source[count] = (unichar)(0);
 
104
      if (base < count)
 
105
        {
 
106
 
 
107
          /*
 
108
           * Now expand decomposable characters into the long format.
 
109
           * Use the 'base' value to avoid re-checking characters which have
 
110
           * already been expanded.
 
111
           */
 
112
          while (base < count)
 
113
            {
 
114
              unichar   *spoint = &source[base];
 
115
              unichar   *tpoint = &target[base];
 
116
              unsigned  newbase = 0;
 
117
 
 
118
              do
 
119
                {
 
120
                  unichar       *dpoint = uni_is_decomp(*spoint);
 
121
 
 
122
                  if (!dpoint)
 
123
                    {
 
124
                      *tpoint++ = *spoint;
 
125
                    }
 
126
                  else
 
127
                    {
 
128
                      while (*dpoint)
 
129
                        {
 
130
                          *tpoint++ = *dpoint++;
 
131
                        }
 
132
                      if (newbase <= 0)
 
133
                        {
 
134
                          newbase = (spoint - source) + 1;
 
135
                        }
 
136
                    }
 
137
                }
 
138
              while (*spoint++);
 
139
 
 
140
              count = tpoint - target;
 
141
              memcpy(&source[base], &target[base], 2*(count - base));
 
142
              source[count] = (unichar)(0);
 
143
              if (newbase > 0)
 
144
                {
 
145
                  base = newbase;
102
146
                }
103
147
              else
104
148
                {
105
 
                  while (*dpoint)
106
 
                    {
107
 
                      *tpoint++ = *dpoint++;
108
 
                    }
109
 
                  notdone = YES;
 
149
                  base = count;
110
150
                }
111
151
            }
112
 
          while (*spoint++);
113
 
 
114
 
          count = tpoint - target;
115
 
          memcpy(source, target, 2*count);
116
 
        }
117
 
 
118
 
      seq->count = count;
119
 
      if (count > 1)
120
 
        {
121
 
          notdone = YES;
122
 
 
123
 
          while (notdone)
 
152
          seq->count = count;
 
153
 
 
154
          /*
 
155
           * Now standardise ordering of all composed character sequences.
 
156
           */
 
157
          if (count > 1)
124
158
            {
125
 
              unichar   *first = seq->chars;
126
 
              unichar   *second = first + 1;
127
 
              unsigned  i;
 
159
              BOOL      notdone = YES;
128
160
 
129
 
              notdone = NO;
130
 
              for (i = 1; i < count; i++)
 
161
              while (notdone)
131
162
                {
132
 
                  if (uni_cop(*second))
 
163
                  unichar       *first = seq->chars;
 
164
                  unichar       *second = first + 1;
 
165
                  unsigned      i;
 
166
 
 
167
                  notdone = NO;
 
168
                  for (i = 1; i < count; i++)
133
169
                    {
134
 
                      if (uni_cop(*first) > uni_cop(*second))
135
 
                        {
136
 
                          unichar       tmp = *first;
137
 
 
138
 
                          *first = *second;
139
 
                          *second = tmp;
140
 
                          notdone = YES;
141
 
                        }
142
 
                      else if (uni_cop(*first) == uni_cop(*second))
143
 
                        {
144
 
                          if (*first > *second)
145
 
                            {
146
 
                               unichar  tmp = *first;
147
 
 
148
 
                               *first = *second;
149
 
                               *second = tmp;
150
 
                               notdone = YES;
151
 
                            }
152
 
                        }
 
170
                      if (uni_cop(*second))
 
171
                        {
 
172
                          if (uni_cop(*first) > uni_cop(*second))
 
173
                            {
 
174
                              unichar   tmp = *first;
 
175
 
 
176
                              *first = *second;
 
177
                              *second = tmp;
 
178
                              notdone = YES;
 
179
                            }
 
180
                          else if (uni_cop(*first) == uni_cop(*second))
 
181
                            {
 
182
                              if (*first > *second)
 
183
                                {
 
184
                                   unichar      tmp = *first;
 
185
 
 
186
                                   *first = *second;
 
187
                                   *second = tmp;
 
188
                                   notdone = YES;
 
189
                                }
 
190
                            }
 
191
                        }
 
192
                      first++;
 
193
                      second++;
153
194
                    }
154
 
                  first++;
155
 
                  second++;
156
195
                }
157
196
            }
158
197
        }
251
290
 * Set up macros for dealing with 'self' on the basis of GSQ_S
252
291
 */
253
292
#if     GSEQ_S == GSEQ_US
254
 
#define GSEQ_ST ivars
 
293
#define GSEQ_ST GSStr
255
294
#define GSEQ_SLEN       s->_count
256
295
#define GSEQ_SGETC(I)   s->_contents.u[I]
257
296
#define GSEQ_SGETR(B,R) memcpy(B, &s->_contents.u[R.location], 2*(R).length)
258
297
#define GSEQ_SRANGE(I)  (*srImp)((id)s, ranSel, I)
259
298
#else
260
299
#if     GSEQ_S == GSEQ_CS
261
 
#define GSEQ_ST ivars
 
300
#define GSEQ_ST GSStr
262
301
#define GSEQ_SLEN       s->_count
263
302
#define GSEQ_SGETC(I)   (unichar)s->_contents.c[I]
264
303
#define GSEQ_SGETR(B,R) ( { \
283
322
 * Set up macros for dealing with 'other' string on the basis of GSQ_O
284
323
 */
285
324
#if     GSEQ_O == GSEQ_US
286
 
#define GSEQ_OT ivars
 
325
#define GSEQ_OT GSStr
287
326
#define GSEQ_OLEN       o->_count
288
327
#define GSEQ_OGETC(I)   o->_contents.u[I]
289
328
#define GSEQ_OGETR(B,R) memcpy(B, &o->_contents.u[R.location], 2*(R).length)
290
329
#define GSEQ_ORANGE(I)  (*orImp)((id)o, ranSel, I)
291
330
#else
292
331
#if     GSEQ_O == GSEQ_CS
293
 
#define GSEQ_OT ivars
 
332
#define GSEQ_OT GSStr
294
333
#define GSEQ_OLEN       o->_count
295
334
#define GSEQ_OGETC(I)   (unichar)o->_contents.c[I]
296
335
#define GSEQ_OGETR(B,R) ( { \
329
368
    [NSException raise: NSRangeException format: @"Invalid location+length."];
330
369
 
331
370
  oLength = GSEQ_OLEN;
332
 
  if (sLength - aRange.location == 0)
 
371
  if (aRange.length == 0)
333
372
    {
334
373
      if (oLength == 0)
335
374
        {
370
409
#endif
371
410
 
372
411
#if     GSEQ_S == GSEQ_NS
373
 
      sgImp = (void (*)())[(id)s methodForSelector: gcrSel];
 
412
      sgImp = (void (*)(NSString*,SEL,unichar*,NSRange))
 
413
        [(id)s methodForSelector: gcrSel];
374
414
      GSEQ_SGETR(sBuf, aRange);
375
415
#else
376
416
#if     GSEQ_S == GSEQ_CS
380
420
#endif
381
421
#endif
382
422
#if     GSEQ_O == GSEQ_NS
383
 
      ogImp = (void (*)())[(id)o methodForSelector: gcrSel];
 
423
      ogImp = (void (*)(NSString*,SEL,unichar*,NSRange))
 
424
        [(id)o methodForSelector: gcrSel];
384
425
      GSEQ_OGETR(oBuf, NSMakeRange(0, oLen));
385
426
#else
386
427
#if     GSEQ_O == GSEQ_CS
446
487
#endif
447
488
 
448
489
#if     GSEQ_S == GSEQ_NS || GSEQ_S == GSEQ_US
449
 
      srImp = (NSRange (*)())[(id)s methodForSelector: ranSel];
 
490
      srImp = (NSRange (*)(NSString*, SEL, unsigned))
 
491
        [(id)s methodForSelector: ranSel];
450
492
#endif
451
493
#if     GSEQ_O == GSEQ_NS || GSEQ_O == GSEQ_US
452
 
      orImp = (NSRange (*)())[(id)o methodForSelector: ranSel];
 
494
      orImp = (NSRange (*)(NSString*, SEL, unsigned))
 
495
        [(id)o methodForSelector: ranSel];
453
496
#endif
454
497
#if     GSEQ_S == GSEQ_NS
455
 
      sgImp = (void (*)())[(id)s methodForSelector: gcrSel];
 
498
      sgImp = (void (*)(NSString*, SEL, unichar*, NSRange))
 
499
        [(id)s methodForSelector: gcrSel];
456
500
#endif
457
501
#if     GSEQ_O == GSEQ_NS
458
 
      ogImp = (void (*)())[(id)o methodForSelector: gcrSel];
 
502
      ogImp = (void (*)(NSString*, SEL, unichar*, NSRange))
 
503
        [(id)o methodForSelector: gcrSel];
459
504
#endif
460
505
 
461
 
 
462
506
      while (sCount < end)
463
507
        {
464
508
          if (oCount >= oLength)
556
600
   * Cache method implementations for getting characters and ranges
557
601
   */
558
602
#if     GSEQ_S == GSEQ_NS
559
 
  scImp = (unichar (*)())[(id)s methodForSelector: caiSel];
560
 
  sgImp = (void (*)())[(id)s methodForSelector: gcrSel];
 
603
  scImp = (unichar (*)(NSString*,SEL,unsigned))
 
604
    [(id)s methodForSelector: caiSel];
 
605
  sgImp = (void (*)(NSString*,SEL,unichar*,NSRange))
 
606
    [(id)s methodForSelector: gcrSel];
561
607
#endif
562
608
#if     GSEQ_O == GSEQ_NS
563
 
  ocImp = (unichar (*)())[(id)o methodForSelector: caiSel];
564
 
  ogImp = (void (*)())[(id)o methodForSelector: gcrSel];
 
609
  ocImp = (unichar (*)(NSString*,SEL,unsigned))
 
610
    [(id)o methodForSelector: caiSel];
 
611
  ogImp = (void (*)(NSString*,SEL,unichar*,NSRange))
 
612
    [(id)o methodForSelector: gcrSel];
565
613
#endif
566
614
#if     GSEQ_S == GSEQ_NS || GSEQ_S == GSEQ_US
567
 
  srImp = (NSRange (*)())[(id)s methodForSelector: ranSel];
 
615
  srImp = (NSRange (*)(NSString*,SEL,unsigned))
 
616
    [(id)s methodForSelector: ranSel];
568
617
#endif
569
618
#if     GSEQ_O == GSEQ_NS || GSEQ_O == GSEQ_US
570
 
  orImp = (NSRange (*)())[(id)o methodForSelector: ranSel];
 
619
  orImp = (NSRange (*)(NSString*,SEL,unsigned))
 
620
    [(id)o methodForSelector: ranSel];
571
621
#endif
572
622
 
573
623
  switch (mask)