This is List-Ordered.m in view mode; [Download] [Up]
/* ------------------------------------------------------------------- #import <objc/List.h> RDR, Inc. Objective-C source file for the class List-Ordered COPYRIGHT (C), 1991, RDR, Inc. ALL RIGHTS RESERVED. Responsible: Approved: RDR:Ernest Prabhakar Date: Rev: 1991-Jun-28 ___ List-Ordered 1. Introduction This Category adds behavior not supplied in the standard list. That includes sorting, searching, and other things that rely on knowing the properties of the object - e.g, a Card. To be searched, objects must implement 'findSTR:' - or, even better, 'findSTR:dir:' To be sorted, objects must implement 'rankRelativeTo:' 2. Revision History ___ The starting point. Ernest Prabhakar/1991-Jun-28 3. Source Code ------------------------------------------------------------------- */ /* ------------------------- Import files ------------------------- */ #import <appkit/nextstd.h> #import <limits.h> #import <regex.h> /* ------------------------ Classes used ------------------------ */ #import "Card.h" #import "Random.h" #import <appkit/Panel.h> /* -------------------------- Defines --------------------------- */ #define ZAlloc(Class) [Class allocFromZone:[self zone]] #define copyIds(From, To, N) bcopy(From, To, sizeof(id) * N) /* ---------------------- Class variables ----------------------- */ static Random *ranGen; /* returns a random number */ /* -------------------- Auxiliary Functions --------------------- */ static int qcomp(const void *a, const void *b) { return[*(id*)a compare:*(id*)b]; } BOOL regexString(const char *expr) { char *result = re_comp((char *)expr); return (result) ? NO : YES; } static void mixup(id *from, id *to, int n) { int i; id *toIndex = to + n; /* Fill in Backwards */ id *toStop = to + (n-- / 5); /* Mix 80% of indices */ while (toIndex > toStop) { /* Pull in at Random */ while (from[i = [ranGen randMax:n]] == nil); *(--toIndex) = from[i]; from[i] = nil; } --from; while (toIndex > to) { /* Get rest */ while (*(++from) == nil); *(--toIndex) = *from; } } /* ------------------------- Constants -------------------------- */ /*==================================================================== Implementation of class List-Ordered ====================================================================*/ #import "List-Ordered.h" @implementation List (Ordered) #ifndef BUGGY /*==================================================================== Import and Export ====================================================================*/ /*-------------------------------------------------------------------- |-importFrom:(NXStream *)stream| Import data using the "Card" object. Expects tab seperated, newline delimited like NXTabular. Returns self. Ernest Prabhakar/1991-Jul-01 --------------------------------------------------------------------*/ -importFrom:(NXStream *)stream { id card=nil; id next; do { card = [ZAlloc(Card) initCount:0]; next = [card importFrom:stream]; if ([card count]) { [self addObject:card]; } else { [card free]; } } while (next); return self; } /*-------------------------------------------------------------------- |-exportTo:(NXStream *)stream| If cards can export, it writes them out in order. Returns self. Ernest Prabhakar/1991-Jul-01 --------------------------------------------------------------------*/ -exportTo:(NXStream *)stream { id *dataIndex = dataPtr; id *dataEnd = dataPtr + numElements; if (![*dataIndex respondsTo:@selector(exportTo:)]) return nil; while (dataIndex < dataEnd) [*dataIndex++ exportTo:stream]; return self; } /*==================================================================== Dispense Objects ====================================================================*/ /*-------------------------------------------------------------------- |-next| Returns object at top. Ernest Prabhakar/1991-Jun-28 --------------------------------------------------------------------*/ -next { return [self removeObjectAt:0]; } /*-------------------------------------------------------------------- |-emptyTo:(List *)aList| Give all to another List End up empty. Returns self. Ernest Prabhakar/1991-Jun-28 --------------------------------------------------------------------*/ -emptyTo:(List *)aList { id card; while (card = [self next]) [aList addObject:card]; return self; } /*-------------------------------------------------------------------- |-(unsigned)dealTo:(List *) handList| Deal contents out equally to all the contents of handList. Returns number of cards remaining. Ernest Prabhakar/1991-Jun-28 --------------------------------------------------------------------*/ -(unsigned)dealTo:(List *) handList { return[self dealTo:handList each:numElements]; } /*-------------------------------------------------------------------- |-(unsigned)dealTo:(List *) handList each:(int)numCards| Deal numCards (or largest equal number) to each item in list. Returns remaining cards. Ernest Prabhakar/1991-Jun-28 --------------------------------------------------------------------*/ -(unsigned)dealTo:(List *) handList each:(int)numCards { int hands = [handList count]; int c, h; if (hands * numCards > numElements) numCards = numElements / hands; for (c = 0; c < numCards; c++) for (h = 0; h < hands; h++) [NX_ADDRESS(handList)[h] addObject:[self next]]; return numElements; } /*==================================================================== Manipulate List ====================================================================*/ /*-------------------------------------------------------------------- |-cutAt:(unsigned)index| Cut List at index. Returns nil if out of bounds, otherwise self. Ernest Prabhakar/1991-Jun-28 --------------------------------------------------------------------*/ -cutAt:(unsigned)index { id *copyPtr; if ((!index) || (index > numElements)) return nil; NX_MALLOC(copyPtr, id, numElements); copyIds(dataPtr, copyPtr, numElements); copyIds(copyPtr + index, dataPtr, numElements - index); copyIds(copyPtr, dataPtr + (numElements - index), index); NX_FREE(copyPtr); return self; } /*-------------------------------------------------------------------- |-shuffle| Randomly Shuffle List. Returns self. Ernest Prabhakar/1991-Jun-28 --------------------------------------------------------------------*/ -shuffle { id *copyPtr; if (!ranGen) ranGen = [ZAlloc(Random) init]; NX_MALLOC(copyPtr, id, numElements); mixup(dataPtr, copyPtr, numElements); mixup(copyPtr, dataPtr, numElements); NX_FREE(copyPtr); return self; } /*-------------------------------------------------------------------- |-sort| Sort using the 'rankRelativeTo:' method. Returns self. Ernest Prabhakar/1991-Jun-28 --------------------------------------------------------------------*/ -sort { if (numElements && [*dataPtr respondsTo:@selector(compare:)]) { qsort((void *)dataPtr, numElements, sizeof(id), qcomp); return self; } return nil; } /*-------------------------------------------------------------------- |-reverse| Reverse the order of Objects in the List. Returns self. Ernest Prabhakar/1991-Jun-28 --------------------------------------------------------------------*/ -reverse { id *copyPtr, *copyIndex; id *dataIndex; NX_MALLOC(copyPtr, id, numElements); copyIds(dataPtr, copyPtr, numElements); dataIndex = dataPtr + numElements; /* Fill in Backwards */ copyIndex = copyPtr; while (dataIndex > dataPtr) /* Get rest */ *(--dataIndex) = *(copyIndex++); NX_FREE(copyPtr); return self; } /*==================================================================== Find a String ====================================================================*/ /*-------------------------------------------------------------------- |-findSTR:(const char *) aString| Find the first object containg this string. Can use any regular expression. The object must recognize 'findSTR:' itself. Returns object, if any, else nil. Ernest Prabhakar/1991-Jun-28 --------------------------------------------------------------------*/ -findSTR:(const char *) aString { return [self findSTR:aString dir:0]; } /*-------------------------------------------------------------------- |-findSTR:(const char *) aString dir:(int)flag| Same as 'findSTR:', but nonzero flag means reverse. Returns self. Ernest Prabhakar/1991-Jun-28 --------------------------------------------------------------------*/ -findSTR:(const char *) aString dir:(int)flag { id *dataIndex = dataPtr-1; id *dataEnd = dataPtr + numElements; if (!regexString(aString)) return nil; while (dataIndex < (dataEnd-1)) { if (!flag) { if ([*(++dataIndex) findSTR:aString]) return *dataIndex; } else { if ([*(--dataEnd) findSTR:aString]) return *dataEnd; } } return nil; } /*-------------------------------------------------------------------- |-findAllSTR:(const char *) aString| Returns all objects containing the specified string. Ernest Prabhakar/1991-Jun-28 --------------------------------------------------------------------*/ -findAllSTR:(const char *) aString { id *dataIndex, *dataEnd; id list; dataEnd = dataPtr + numElements; list = [ZAlloc(List) init]; if (regexString(aString)) for (dataIndex = dataPtr; dataIndex < dataEnd; ++dataIndex) if ([*dataIndex findSTR:aString]) [list addObject:*dataIndex]; if ([list count]) { return list; } else { [list free]; return nil; } } #endif @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.