/[gnustep]/gnustep/dev-libs/gdl2/EOControl/EOSortOrdering.m
ViewVC logotype

Contents of /gnustep/dev-libs/gdl2/EOControl/EOSortOrdering.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (show annotations) (download)
Mon Aug 25 20:01:59 2003 UTC (20 years, 8 months ago) by ayers
Branch: MAIN
Changes since 1.9: +4 -4 lines
	* *.h/m:  Updated to new header layout.
	* Tools/eoutil.m:  Added missing include.

1 /**
2 EOSortOrdering.m <title>EOSortOrdering</title>
3
4 Copyright (C) 2000-2002 Free Software Foundation, Inc.
5
6 Author: Mirko Viviani <mirko.viviani@rccr.cremona.it>
7 Date: February 2000
8
9 $Revision: 1.9 $
10 $Date: 2003/07/11 19:04:05 $
11
12 <abstract></abstract>
13
14 This file is part of the GNUstep Database Library.
15
16 <license>
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Library General Public
19 License as published by the Free Software Foundation; either
20 version 2 of the License, or (at your option) any later version.
21
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Library General Public License for more details.
26
27 You should have received a copy of the GNU Library General Public
28 License along with this library; see the file COPYING.LIB.
29 If not, write to the Free Software Foundation,
30 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 </license>
32 **/
33
34 #include "config.h"
35
36 RCS_ID("$Id: EOSortOrdering.m,v 1.9 2003/07/11 19:04:05 ayers Exp $")
37
38 #ifndef NeXT_Foundation_LIBRARY
39 #include <Foundation/NSCoder.h>
40 #include <Foundation/NSException.h>
41 #include <Foundation/NSDebug.h>
42 #include <Foundation/NSNull.h>
43 #else
44 #include <Foundation/Foundation.h>
45 #endif
46
47 #ifndef GNUSTEP
48 #include <GNUstepBase/GNUstep.h>
49 #endif
50
51 #include <EOControl/EOSortOrdering.h>
52 #include <EOControl/EOKeyValueCoding.h>
53 #include <EOControl/EOKeyValueArchiver.h>
54 #include <EOControl/EODebug.h>
55
56 #define EONull NSNull
57
58 @implementation EOSortOrdering
59
60 /**
61 * Returns an autoreleased EOSortOrdering initilaized with key and selector.
62 * The selector should take an id as an argument and return an
63 * NSComparisonResult value. This method calls
64 * [EOSortOrdering-initWithKey:selector:].
65 */
66 + (EOSortOrdering *) sortOrderingWithKey: (NSString *)key
67 selector: (SEL)selector
68 {
69 return AUTORELEASE([[self alloc] initWithKey: key
70 selector: selector]);
71 }
72
73 - (void) encodeWithCoder: (NSCoder *)coder
74 {
75 [coder encodeValueOfObjCType: @encode(SEL) at: _selector];
76 [coder encodeObject: _key];
77 }
78
79 - (id) initWithCoder: (NSCoder *)coder
80 {
81 self = [super init];
82
83 [coder decodeValueOfObjCType: @encode(SEL) at: &_selector];
84 _key = RETAIN([coder decodeObject]);
85
86 return self;
87 }
88
89 - (id)copyWithZone:(NSZone *)zone
90 {
91 if (NSShouldRetainWithZone(self, zone))
92 {
93 return RETAIN(self);
94 }
95 return [[[self class] allocWithZone: zone]
96 initWithKey: _key selector: _selector];
97 }
98
99 /**<init />
100 * Initializes the receiver with a copy of key and the selector. The selector
101 * should take an id as an argument and return an NSComparisonResult value.
102 */
103 - (id) initWithKey: (NSString *)key selector: (SEL)selector
104 {
105 self = [super init];
106
107 ASSIGNCOPY(_key, key);
108 _selector = selector;
109
110 return self;
111 }
112
113 /**
114 * Returns the key of the receiver.
115 */
116 - (NSString *) key
117 {
118 return _key;
119 }
120
121 /**
122 * Returns the selector of the receiver. The selector should take an id as
123 * an argument and return an NSComparisonResult value.
124 */
125 - (SEL) selector
126 {
127 return _selector;
128 }
129
130 - (id) initWithKeyValueUnarchiver: (EOKeyValueUnarchiver*)unarchiver
131 {
132 EOFLOGObjectFnStartOrCond(@"EOSortOrdering");
133
134 if ((self = [super init]))
135 {
136 NSString *selectorName;
137
138 ASSIGN(_key, [unarchiver decodeObjectForKey: @"key"]);
139 selectorName = [unarchiver decodeObjectForKey: @"selectorName"];
140
141 if (selectorName)
142 _selector = NSSelectorFromString(selectorName);
143 }
144
145 EOFLOGObjectFnStopOrCond(@"EOSortOrdering");
146
147 return self;
148 }
149
150 - (void) encodeWithKeyValueArchiver: (EOKeyValueArchiver*)archiver
151 {
152 [archiver encodeObject: _key forKey: @"key"];
153 if (_selector)
154 {
155 [archiver encodeObject: NSStringFromSelector(_selector)
156 forKey: @"selectorName"];
157 }
158 }
159
160 /**
161 * Returns a human readable representation of the receiver.
162 */
163 - (NSString *) description
164 {
165 return [NSString stringWithFormat:@"<%@ %p - %@ %@>",
166 NSStringFromClass(isa),
167 (void*)self,
168 _key,
169 NSStringFromSelector(_selector)];
170 }
171 @end
172
173
174 @implementation NSArray (EOKeyBasedSorting)
175
176 static NSComparisonResult
177 compareUsingSortOrderings(id left,
178 id right,
179 void* vpSortOrders)
180 {
181 static EONull *null = nil;
182 NSArray *sortOrders = (NSArray *)vpSortOrders;
183 NSComparisonResult r = NSOrderedSame;
184 unsigned int i;
185 unsigned int sortOrdCnt = [sortOrders count];
186
187 if (null == nil)
188 {
189 null = [EONull null];
190 }
191
192 /* Loop over all sort orderings until we have an ordering difference. */
193 for (i=0; (r == NSOrderedSame) && (i < sortOrdCnt); i++)
194 {
195 EOSortOrdering *sortOrd = [sortOrders objectAtIndex: i];
196 NSString *key = [sortOrd key];
197 SEL compSel = [sortOrd selector];
198 id leftVal = [left valueForKeyPath: key];
199 id rightVal = [right valueForKeyPath: key];
200 BOOL inverted = NO;
201 NSComparisonResult (*imp)(id, SEL, id);
202
203 /* Use EONull instead of nil. */
204 leftVal = (leftVal != nil)?(leftVal) :(null);
205 rightVal = (rightVal != nil)?(rightVal):(null);
206
207 /* Insure that EONull is not the parameter for
208 comparisons with other classes. */
209 if (rightVal == null)
210 {
211 rightVal = leftVal;
212 leftVal = null;
213 inverted = YES;
214 }
215
216 imp = (NSComparisonResult (*)(id, SEL, id))
217 [leftVal methodForSelector: compSel];
218 NSCAssert3(imp!=NULL,
219 @"Invalid comparison selector:%@ for object:<%@ 0x%x>",
220 NSStringFromSelector(compSel),
221 NSStringFromClass([leftVal class]),
222 leftVal);
223 r = (*imp)(leftVal, compSel, rightVal);
224
225 /* If we inverted the parameters, we must switch the result*/
226 if (inverted == YES)
227 {
228 r = ~r + 1;
229 }
230 }
231
232 return r;
233 }
234
235
236 /**
237 * Returns an array contaning the of the objects of the reveiver sorted
238 * according to the provided array of EOSortOrderings.
239 */
240 - (NSArray *) sortedArrayUsingKeyOrderArray: (NSArray *)orderArray
241 {
242 if ([self count] > 1)
243 {
244 return [self sortedArrayUsingFunction: compareUsingSortOrderings
245 context: orderArray];
246 }
247 else
248 {
249 return self;
250 }
251 }
252
253 @end
254
255
256 @implementation NSMutableArray (EOKeyBasedSorting)
257
258 /**
259 * Sorts the reveiver according to the provided array of EOSortOrderings.
260 */
261 - (void) sortUsingKeyOrderArray: (NSArray *)orderArray
262 {
263 if ([self count] > 1)
264 {
265 [self sortUsingFunction: compareUsingSortOrderings
266 context: orderArray];
267 }
268 }
269
270 @end
271
272
273 @implementation NSObject (EOSortOrderingComparison)
274
275 /**
276 * Default implementation of EOCompareAscending.
277 * This implementation returns the result of compare:.
278 * Concrete classes should either override this method or compare:
279 * to return a meaningful NSComparisonResult.
280 */
281 - (NSComparisonResult) compareAscending: (id)other
282 {
283 return [self compare: other];
284 }
285
286 /**
287 * Default implementation of EOCompareDescending.
288 * This implementation returns the inverted result of compare:.
289 * Concrete classes should either override this method or compare:
290 * to return a meaningful NSComparisonResult.
291 */
292 - (NSComparisonResult) compareDescending: (id)other
293 {
294 NSComparisonResult result = [self compare: other];
295
296 return (~result + 1);
297 }
298
299 /**
300 * Default implementation of EOCompareCaseInsensitiveAscending.
301 * This implementation returns the result of compare:.
302 * Concrete classes should either override this method or compare:
303 * to return a meaningful NSComparisonResult.
304 */
305 - (NSComparisonResult) compareCaseInsensitiveAscending: (id)other
306 {
307 return [self compare: other];
308 }
309
310 /**
311 * Default implementation of EOCompareCaseInsensitiveDescending.
312 * This implementation returns the inverted result of compare:.
313 * Concrete classes should either override this method or compare:
314 * to return a meaningful NSComparisonResult.
315 */
316 - (NSComparisonResult) compareCaseInsensitiveDescending: (id)other
317 {
318 NSComparisonResult result = [self compare: other];
319
320 return (~result + 1);
321 }
322
323 @end
324
325
326 @implementation EONull (EOSortOrderingComparison)
327
328 /**
329 * Implementation of EOCompareAscending for EONull.
330 * When compared to another EONull, return NSOrderedSame.
331 * Otherwise NSOrderdAscening. This leads to EONulls to be at the begining
332 * of arrays sorted with EOCompareAscending.
333 */
334 - (NSComparisonResult) compareAscending: (id)other
335 {
336 if (self == other)
337 return NSOrderedSame;
338
339 return NSOrderedAscending;
340 }
341
342 /**
343 * Implementation of EOCompareDescending for EONull.
344 * When compared to another EONull, return NSOrderedSame.
345 * Otherwise NSOrderdDescening. This leads to EONulls to be at the end
346 * of arrays sorted with EOCompareDescending.
347 */
348 - (NSComparisonResult) compareDescending: (id)other
349 {
350 if (self == other)
351 return NSOrderedSame;
352
353 return NSOrderedDescending;
354 }
355
356 /**
357 * Implementation of EOCompareCaseInsensativeAscending for EONull.
358 * When compared to another EONull, return NSOrderedSame.
359 * Otherwise NSOrderdAscening. This leads to EONulls to be at the begining
360 * of arrays sorted with EOCompareCaseInsensitiveAscending.
361 */
362 - (NSComparisonResult) compareCaseInsensitiveAscending: (id)other
363 {
364 if (self == other)
365 return NSOrderedSame;
366
367 return NSOrderedAscending;
368 }
369
370 /**
371 * Implementation of EOCompareCaseInsensativeDescending for EONull.
372 * When compared to another EONull, return NSOrderedSame.
373 * Otherwise NSOrderdDescening. This leads to EONulls to be at the end
374 * of arrays sorted with EOCompareCaseInsensativeDescending.
375 */
376 - (NSComparisonResult) compareCaseInsensitiveDescending: (id)other
377 {
378 if (self == other)
379 return NSOrderedSame;
380
381 return NSOrderedDescending;
382 }
383
384 @end
385
386
387
388 @implementation NSString (EOSortOrderingComparison)
389
390 /**
391 * Implementation of EOCompareCaseInsensativeDescending for NSString.
392 * This method simply returns the result
393 * of calling caseInsensitiveCompare:.
394 */
395 - (NSComparisonResult) compareCaseInsensitiveAscending: (id)other
396 {
397 return [self caseInsensitiveCompare: other];
398 }
399
400 /**
401 * Implementation of EOCompareCaseInsensativeDescending for NSString.
402 * This method simply returns the inverted result
403 * of calling caseInsensitiveCompare:.
404 */
405 - (NSComparisonResult) compareCaseInsensitiveDescending: (id)other
406 {
407 NSComparisonResult result = [self caseInsensitiveCompare: other];
408
409 return (~result + 1);
410 }
411
412 @end

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26