home *** CD-ROM | disk | FTP | other *** search
- //=============================================================================
- //
- // Copyright (C) 1995 by Paul S. McCarthy and Eric Sunshine.
- // Written by Paul S. McCarthy and Eric Sunshine.
- // All Rights Reserved.
- //
- // This notice may not be removed from this source code.
- //
- // This object is included in the MiscKit by permission from the authors
- // and its use is governed by the MiscKit license, found in the file
- // "License.rtf" in the MiscKit distribution. Please refer to that file
- // for a list of all applicable permissions and restrictions.
- //
- //=============================================================================
- //-----------------------------------------------------------------------------
- // MiscIntList.M
- //
- // A dynamically sizable list of integers.
- //
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // $Id: MiscIntList.M,v 1.5 95/10/03 05:08:16 zarnuk Exp $
- // $Log: MiscIntList.M,v $
- // Revision 1.5 95/10/03 05:08:16 zarnuk
- // Fixed compiler warning.
- //
- // Revision 1.4 95/10/03 04:57:41 sunshine
- // Fixed -init so Storage is allocated from [self zone]. Added copyFromZone:,
- // initFromString:, and addIntList:.
- //
- // Revision 1.3 95/10/03 03:56:44 sunshine
- // Fixed bug where -readFromString: couldn't parse negative numbers.
- //
- // Revision 1.2 95/09/30 19:01:05 zarnuk
- // Added sting read/write methods. Added rawData method.
- //-----------------------------------------------------------------------------
- #import <misckit/MiscIntList.h>
-
- extern "Objective-C" {
- #import <objc/Storage.h>
- }
-
- extern "C" {
- #include <stdlib.h>
- #include <stdio.h>
- }
-
- //-----------------------------------------------------------------------------
- // std_cmp
- //-----------------------------------------------------------------------------
- static int std_cmp( void*, int x, int y )
- {
- if (x < y)
- return -1;
- if (y > x)
- return 1;
- return 0;
- }
-
-
- //-----------------------------------------------------------------------------
- // qsort_cmp
- //-----------------------------------------------------------------------------
- static MiscIntListCompareFunc cmp_func = 0;
- static void* cmp_data = 0;
- static int qsort_cmp( void const* px, void const* py )
- {
- return (*cmp_func)( cmp_data, *((int const*)px), *((int const*)py) );
- }
-
-
- @implementation MiscIntList
-
- //-----------------------------------------------------------------------------
- // init
- //-----------------------------------------------------------------------------
- - init
- {
- [super init];
- array = [[Storage allocFromZone: [self zone]]
- initCount:0 elementSize:sizeof(int) description:"i"];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // initFromString:
- //-----------------------------------------------------------------------------
- - initFromString: (char const*) s
- {
- [self init];
- [self readFromString:s];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // free
- //-----------------------------------------------------------------------------
- - free
- {
- [array free];
- return [super free];
- }
-
-
- //-----------------------------------------------------------------------------
- // copyFromZone:
- //-----------------------------------------------------------------------------
- - copyFromZone: (NXZone*) zone
- {
- MiscIntList* clone = [super copyFromZone:zone];
- clone->array = [array copyFromZone:zone];
- return clone;
- }
-
-
- //-----------------------------------------------------------------------------
- // empty
- //-----------------------------------------------------------------------------
- - empty
- {
- [array empty];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // count
- //-----------------------------------------------------------------------------
- - (unsigned int) count
- {
- return [array count];
- }
-
-
- //-----------------------------------------------------------------------------
- // intAt:
- //-----------------------------------------------------------------------------
- - (int) intAt: (unsigned int) pos
- {
- return (pos < [self count] ? (*(int*)[array elementAt:pos]) : 0);
- }
-
-
- //-----------------------------------------------------------------------------
- // addInt:
- //-----------------------------------------------------------------------------
- - (void) addInt: (int) value
- {
- [self insertInt: value at: [self count]];
- }
-
-
- //-----------------------------------------------------------------------------
- // addIntList:
- //-----------------------------------------------------------------------------
- - (void) addIntList: (MiscIntList*) list
- {
- if (list != 0)
- {
- unsigned int const lim = [list count];
- for (unsigned int i = 0; i < lim; i++)
- [self addInt: [list intAt:i]];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // insertInt:at:
- //-----------------------------------------------------------------------------
- - (void) insertInt: (int) value at: (unsigned int) pos
- {
- [array insertElement: &value at: pos];
- }
-
-
- //-----------------------------------------------------------------------------
- // removeIntAt:
- //-----------------------------------------------------------------------------
- - (void) removeIntAt: (unsigned int) pos
- {
- [array removeElementAt: pos];
- }
-
-
- //-----------------------------------------------------------------------------
- // replaceIntAt:with:
- //-----------------------------------------------------------------------------
- - (void) replaceIntAt: (unsigned int) pos with: (int) value
- {
- [array replaceElementAt:pos with:&value];
- }
-
-
- //-----------------------------------------------------------------------------
- // sortUsing:data:
- //-----------------------------------------------------------------------------
- - (void) sortUsing:(MiscIntListCompareFunc)func data:(void*)data
- {
- unsigned int const N = [self count];
- if (N > 1)
- {
- cmp_func = (func ? func : std_cmp);
- cmp_data = data;
- qsort( [array elementAt:0], N, sizeof(int), qsort_cmp );
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // sort
- //-----------------------------------------------------------------------------
- - (void) sort
- {
- [self sortUsing:&std_cmp data:0];
- }
-
-
- //-----------------------------------------------------------------------------
- // append_char
- //-----------------------------------------------------------------------------
- static void append_char( char c, char*& buff, int& buff_size,
- int& len, BOOL can_expand )
- {
- if (buff != 0)
- {
- if (len >= buff_size)
- if (!can_expand)
- buff = 0;
- else
- {
- buff_size <<= 1; // Double the size.
- buff = (char*) realloc( buff, buff_size );
- }
- if (buff != 0)
- buff[ len++ ] = c;
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // append_int
- //-----------------------------------------------------------------------------
- static void append_int( int x, char*& buff, int& buff_size,
- int& len, BOOL can_expand )
- {
- char tmp[ 64 ];
- sprintf( tmp, "%d", x );
- for (char const* t = tmp; *t != 0 && buff != 0; t++)
- append_char( *t, buff, buff_size, len, can_expand );
- }
-
-
- //-----------------------------------------------------------------------------
- // - writeToString:size:canExpand:
- //-----------------------------------------------------------------------------
- - (char*) writeToString: (char*) buff size: (int) buff_size
- canExpand:(BOOL) can_expand
- {
- int const START_SIZE = 32;
- int i,x,len;
- int const lim = [self count];
-
- if ((buff == 0 || buff_size == 0) && can_expand)
- {
- buff = (char*) malloc( START_SIZE );
- buff_size = START_SIZE;
- }
-
- if (buff_size == 0)
- buff = 0;
-
- len = 0;
- for (i = 0; buff != 0 && i < lim; i++)
- {
- x = [self intAt:i];
- if (i > 0)
- append_char( ' ', buff, buff_size, len, can_expand );
- append_int( x, buff, buff_size, len, can_expand );
- }
-
- append_char( '\0', buff, buff_size, len, can_expand );
-
- return buff;
- }
-
-
- //-----------------------------------------------------------------------------
- // - writeToString:size:
- //-----------------------------------------------------------------------------
- - (char*) writeToString: (char*) buff size: (int) buff_size
- {
- return [self writeToString:buff size:buff_size canExpand:NO];
- }
-
-
- //-----------------------------------------------------------------------------
- // writeToString
- //-----------------------------------------------------------------------------
- - (char*) writeToString
- {
- return [self writeToString:0 size:0 canExpand:YES];
- }
-
-
- //-----------------------------------------------------------------------------
- // readFromString:
- //-----------------------------------------------------------------------------
- - (int) readFromString: (char const*) s
- {
- [self empty];
- if (s != 0)
- {
- while (*s != 0)
- {
- while (*s != 0 && *s != '-' && (*s < '0' || '9' < *s))
- s++;
-
- BOOL is_neg = NO;
- if (*s == '-')
- {
- is_neg = YES;
- s++;
- }
-
- if ('0' <= *s && *s <= '9')
- {
- int x = 0;
- do {
- x = x * 10 + *s - '0';
- s++;
- }
- while ('0' <= *s && *s <= '9');
- [self addInt: (is_neg ? -x : x)];
- }
- }
- }
- return [self count];
- }
-
-
- //-----------------------------------------------------------------------------
- // rawData
- //-----------------------------------------------------------------------------
- - (int const*) rawData
- {
- if ([self count] == 0)
- return 0;
- return (int const*) [array elementAt: 0];
- }
-
- @end
-