This is LinkList.m in view mode; [Download] [Up]
/* Implementation for Objective-C LinkList collection object Copyright (C) 1993 R. Andrew McCallum <mccallum@cs.rochester.edu> Dept. of Computer Science, U. of Rochester, Rochester, NY 14627 This file is part of the GNU Objective-C Collection library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <coll/LinkList.h> #include <objc/objc-api.h> #include <coll/IndexedCollectionPrivate.h> @implementation LinkList (ErrorReporting) - errorElementNotLinking: (elt)anElement inMethod: (SEL)aSel { [self warning:"in %s, element=0x%x does not conform to <ListLinking>"]; return self; } @end @implementation LinkList + initialize { if (self == [LinkList class]) [self setVersion:-1]; /* alpha release */ return self; } /* This is the designated initializer of this class */ - init { [super initDescription:"@"]; _count = 0; _firstLink = nil; return self; } /* Override the designated initializer for our superclass IndexedCollection to make sure we have object values. */ - initDescription: (const char *)description { if (*description != _C_ID) [self error:"LinkList contents must be objects conforming to " "<DoubleLinking> protocol"]; [self init]; return self; } /* These next four methods are the only ones that change the values of the instance variables _count, _firstLink, except for "-initDescription:". */ - (elt) removeElement: (elt)oldElement { if (_firstLink == oldElement.id_t) { if (_count > 1) _firstLink = [oldElement.id_t nextLink]; else _firstLink = nil; } [[oldElement.id_t nextLink] setPrevLink:[oldElement.id_t prevLink]]; [[oldElement.id_t prevLink] setNextLink:[oldElement.id_t nextLink]]; _count--; return oldElement; } - insertElement: (elt)newElement after: (elt)oldElement { if (_count == 0) { /* link to self */ _firstLink = newElement.id_t; [newElement.id_t setNextLink:newElement.id_t]; [newElement.id_t setPrevLink:newElement.id_t]; } else { [newElement.id_t setNextLink:[oldElement.id_t nextLink]]; [newElement.id_t setPrevLink:oldElement.id_t]; [[oldElement.id_t nextLink] setPrevLink:newElement.id_t]; [oldElement.id_t setNextLink:newElement.id_t]; } _count++; return self; } - insertElement: (elt)newElement before: (elt)oldElement { if (oldElement.id_t == _firstLink) _firstLink = newElement.id_t; if (_count == 0) { /* Link to self */ [newElement.id_t setNextLink:newElement.id_t]; [newElement.id_t setPrevLink:newElement.id_t]; } else { [newElement.id_t setPrevLink:[oldElement.id_t prevLink]]; [newElement.id_t setNextLink:oldElement.id_t]; [[oldElement.id_t prevLink] setNextLink:newElement.id_t]; [oldElement.id_t setPrevLink:newElement.id_t]; } _count++; return self; } - (elt) replaceElement: (elt)oldElement with: (elt)newElement { if (oldElement.id_t == _firstLink) _firstLink = newElement.id_t; [newElement.id_t setNextLink:[oldElement.id_t nextLink]]; [newElement.id_t setPrevLink:[oldElement.id_t prevLink]]; [[oldElement.id_t prevLink] setNextLink:newElement.id_t]; [[oldElement.id_t nextLink] setPrevLink:newElement.id_t]; return oldElement; } /* End of methods that change the instance variables. */ - appendElement: (elt)newElement { [self insertElement:newElement after:[self lastElement]]; return self; } - prependElement: (elt)newElement { [self insertElement:newElement before:_firstLink]; return self; } - insertElement: (elt)newElement atIndex: (unsigned)index { if (INDEX_RANGE_WARNING(index, (_count+1))) return nil; if (index == _count) [self appendElement:newElement]; else [self insertElement:newElement before:[self elementAtIndex:index]]; return self; } - (elt) removeElementAtIndex: (unsigned)index { if (INDEX_RANGE_WARNING(index, _count)) return COLL_NO_ELEMENT; [self removeElement:[self elementAtIndex:index]]; return self; } - (elt) elementAtIndex: (unsigned)index { id <ListLinking> aLink; if (INDEX_RANGE_WARNING(index, _count)) return COLL_NO_ELEMENT; if (index < _count / 2) for (aLink = _firstLink; index; aLink = [aLink nextLink], index--) ; else for (aLink = [_firstLink prevLink], index = _count - index - 1; index; aLink = [aLink prevLink], index--) ; return aLink; } - (elt) firstElement { return _firstLink; } - (elt) lastElement { if (_count) return [_firstLink prevLink]; else return COLL_NO_ELEMENT; } - (BOOL) getNextElement:(elt *)anElementPtr withEnumState: (void**)enumState { if (*enumState == _firstLink) return NO; else if (!(*enumState)) *enumState = _firstLink; *anElementPtr = *enumState; *enumState = [(id)(*enumState) nextLink]; return YES; } - (BOOL) getPrevElement:(elt *)anElementPtr withEnumState: (void**)enumState { if (*enumState == _firstLink) return NO; if (!(*enumState)) *enumState = _firstLink; *enumState = [(id)(*enumState) prevLink]; *anElementPtr = *enumState; return YES; } - withElementsCall: (void(*)(elt))aFunc whileTrue:(BOOL *)flag { id link; unsigned i; for (link = _firstLink, i = 0; *flag && i < _count; link = [link nextLink], i++) { aFunc(link); } return self; } - withElementsInReverseCall: (void(*)(elt))aFunc whileTrue:(BOOL *)flag { id link; unsigned i; if (!_firstLink) return self; for (link = [_firstLink prevLink], i = 0; *flag && i < _count; link = [link prevLink], i++) { aFunc(link); } return self; } - (unsigned) count { return _count; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.