mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 00:11:26 +00:00
New file.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@2301 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
92282eff6f
commit
d0edc9a79c
11 changed files with 3982 additions and 0 deletions
382
Source/NSGSequence.m
Normal file
382
Source/NSGSequence.m
Normal file
|
@ -0,0 +1,382 @@
|
|||
/* Implementation of composite character sequence class for GNUSTEP
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Stevo Crvenkovski
|
||||
Date: March 1997
|
||||
|
||||
This file is part of the GNUstep Base 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 <gnustep/base/preface.h>
|
||||
#include <gnustep/base/Coding.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSCharacterSet.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSValue.h>
|
||||
#include <Foundation/NSDictionary.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <gnustep/base/IndexedCollection.h>
|
||||
#include <gnustep/base/IndexedCollectionPrivate.h>
|
||||
#include <limits.h>
|
||||
#include <string.h> // for strstr()
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <gnustep/base/NSGSequence.h>
|
||||
#include <gnustep/base//Unicode.h>
|
||||
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
@implementation NSGSequence
|
||||
|
||||
// Creating Temporary Sequences
|
||||
|
||||
+ (NSGSequence*) sequenceWithString: (NSString*) aString
|
||||
range: (NSRange)aRange
|
||||
{
|
||||
return [[[self alloc] initWithString: aString range: aRange]
|
||||
autorelease];
|
||||
}
|
||||
|
||||
+ (NSGSequence*) sequenceWithSequence: (NSGSequence*) aSequence
|
||||
|
||||
{
|
||||
return [[[self alloc]
|
||||
initWithSequence: aSequence]
|
||||
autorelease];
|
||||
}
|
||||
|
||||
+ (NSGSequence*) sequenceWithCharacters: (unichar *) characters
|
||||
length: (int) len
|
||||
{
|
||||
return [[[self alloc]
|
||||
initWithCharacters: characters length: len]
|
||||
autorelease];
|
||||
}
|
||||
|
||||
// Initializing Newly Allocated Sequences
|
||||
|
||||
// xxx take care of _normalize in all init* methods
|
||||
- (id) init
|
||||
{
|
||||
return [self initWithString:@"" range: NSMakeRange(0,0)];
|
||||
}
|
||||
|
||||
- (id) initWithString: (NSString*)string
|
||||
range: (NSRange)aRange
|
||||
{
|
||||
unichar *s;
|
||||
if (aRange.location > [string length])
|
||||
[NSException raise: NSRangeException format:@"Invalid location."];
|
||||
|
||||
if (aRange.length > ([string length] - aRange.location))
|
||||
[NSException raise: NSRangeException format:@"Invalid location+length."];
|
||||
OBJC_MALLOC(s, unichar, aRange.length+1);
|
||||
[string getCharacters:s range: aRange];
|
||||
s[aRange.length] = (unichar)0;
|
||||
return [self initWithCharactersNoCopy:s length: aRange.length freeWhenDone:YES];
|
||||
}
|
||||
|
||||
- (id) initWithSequence: (NSGSequence*) aSequence
|
||||
{
|
||||
unichar *s;
|
||||
int len=[aSequence length];
|
||||
OBJC_MALLOC(s, unichar, len+1);
|
||||
[aSequence getCharacters:s];
|
||||
s[len] = (unichar)0;
|
||||
return [self initWithCharactersNoCopy:s length:len freeWhenDone:YES];
|
||||
}
|
||||
|
||||
- (id) initWithCharactersNoCopy: (unichar*)chars
|
||||
length: (unsigned int)length
|
||||
freeWhenDone: (BOOL)flag
|
||||
{
|
||||
_count = length;
|
||||
_contents_chars = chars;
|
||||
_free_contents = flag;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithCharacters: (const unichar*)chars
|
||||
length: (unsigned int)length
|
||||
{
|
||||
unichar *s;
|
||||
OBJC_MALLOC(s, unichar, length+1);
|
||||
if (chars)
|
||||
memcpy(s, chars,2*length);
|
||||
s[length] = (unichar)0;
|
||||
return [self initWithCharactersNoCopy:s length:length freeWhenDone:YES];
|
||||
}
|
||||
|
||||
// Getting a Length of Sequence
|
||||
|
||||
- (unsigned int) length
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
|
||||
// Accessing Characters
|
||||
|
||||
- (unichar) characterAtIndex: (unsigned int)index
|
||||
{
|
||||
/* xxx raise NSException instead of assert. */
|
||||
assert(index < [self length]);
|
||||
return _contents_chars[index];
|
||||
}
|
||||
|
||||
- (unichar) baseCharacter
|
||||
{
|
||||
if(![self isNormalized])
|
||||
[self normalize];
|
||||
return _contents_chars[0];
|
||||
}
|
||||
|
||||
- (unichar) precomposedCharacter
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
return _contents_chars[0];
|
||||
}
|
||||
|
||||
/* Inefficient. */
|
||||
- (void) getCharacters: (unichar*)buffer
|
||||
{
|
||||
[self getCharacters:buffer range:((NSRange){0,[self length]})];
|
||||
return;
|
||||
}
|
||||
|
||||
/* Inefficient. */
|
||||
- (void) getCharacters: (unichar*)buffer
|
||||
range: (NSRange)aRange
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < aRange.length; i++)
|
||||
{
|
||||
buffer[i] = [self characterAtIndex: aRange.location+i];
|
||||
}
|
||||
}
|
||||
|
||||
//for debuging
|
||||
- (NSString*) description
|
||||
{
|
||||
unichar * point;
|
||||
point=_contents_chars;
|
||||
while(*point)
|
||||
printf("%X ",*point++);
|
||||
printf("\n");
|
||||
return @"";
|
||||
}
|
||||
|
||||
- (NSGSequence*) decompose
|
||||
{
|
||||
#define MAXDEC 18
|
||||
|
||||
unichar *source;
|
||||
unichar *target;
|
||||
unichar *spoint;
|
||||
unichar *tpoint;
|
||||
unichar *dpoint;
|
||||
BOOL notdone;
|
||||
|
||||
OBJC_MALLOC(source, unichar, _count*MAXDEC+1);
|
||||
OBJC_MALLOC(target, unichar, _count*MAXDEC+1);
|
||||
|
||||
spoint = source;
|
||||
tpoint = target;
|
||||
|
||||
if (_count)
|
||||
memcpy(source, _contents_chars,2*_count);
|
||||
source[_count]=(unichar)(0);
|
||||
|
||||
do
|
||||
{
|
||||
notdone=FALSE;
|
||||
do
|
||||
{
|
||||
if(!(dpoint=uni_is_decomp(*spoint)))
|
||||
*tpoint++ = *spoint;
|
||||
else
|
||||
{
|
||||
while(*dpoint)
|
||||
*tpoint++=*dpoint++;
|
||||
notdone=TRUE;
|
||||
} /* else */
|
||||
} while(*spoint++);
|
||||
|
||||
*tpoint=(unichar)0; // *** maybe not needed
|
||||
|
||||
memcpy(source, target,2*(_count*MAXDEC+1));
|
||||
|
||||
tpoint = target; // ***
|
||||
spoint = source; // ***
|
||||
|
||||
} while(notdone);
|
||||
|
||||
return [self initWithCharacters: source length: uslen(source)];
|
||||
}
|
||||
|
||||
- (NSGSequence*) order
|
||||
{
|
||||
unichar *first,*second,tmp;
|
||||
int count,len;
|
||||
BOOL notdone;
|
||||
|
||||
do
|
||||
{
|
||||
notdone=NO;
|
||||
first=_contents_chars;
|
||||
second=first+1;
|
||||
len=[self length];
|
||||
for(count=1;count<len;count++)
|
||||
{
|
||||
if(uni_cop(*second))
|
||||
{
|
||||
if(uni_cop(*first)>uni_cop(*second))
|
||||
{
|
||||
tmp= *first;
|
||||
*first= *second;
|
||||
*second=tmp;
|
||||
notdone=YES;
|
||||
}
|
||||
}
|
||||
first++;
|
||||
second++;
|
||||
}
|
||||
} while(notdone);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSGSequence*) normalize
|
||||
{
|
||||
if(![self isNormalized])
|
||||
{
|
||||
[[self decompose] order];
|
||||
_normalized=YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) isEqual: (NSGSequence*) aSequence
|
||||
{
|
||||
return [self compare:aSequence]==NSOrderedSame;
|
||||
}
|
||||
|
||||
- (BOOL) isNormalized
|
||||
{
|
||||
return _normalized;
|
||||
}
|
||||
|
||||
- (BOOL) isComposite
|
||||
{
|
||||
if(uni_is_decomp(_contents_chars[0]))
|
||||
return YES;
|
||||
else
|
||||
if([self length]<2)
|
||||
return NO;
|
||||
else
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSGSequence*) maxComposed
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSGSequence*) lowercase
|
||||
{
|
||||
unichar *s;
|
||||
int count;
|
||||
int len=[self length];
|
||||
OBJC_MALLOC(s, unichar,len +1);
|
||||
for(count=0;count<len;count++)
|
||||
s[count]=uni_tolower(_contents_chars[count]);
|
||||
s[len] = (unichar)0;
|
||||
return [NSGSequence sequenceWithCharacters:s length:len];
|
||||
}
|
||||
|
||||
- (NSGSequence*) uppercase
|
||||
{
|
||||
unichar *s;
|
||||
int count;
|
||||
int len=[self length];
|
||||
OBJC_MALLOC(s, unichar,len +1);
|
||||
for(count=0;count<len;count++)
|
||||
s[count]=uni_toupper(_contents_chars[count]);
|
||||
s[len] = (unichar)0;
|
||||
return [NSGSequence sequenceWithCharacters:s length:len];
|
||||
}
|
||||
|
||||
- (NSGSequence*) titlecase
|
||||
{
|
||||
[self notImplemented:_cmd];
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Inefficient */
|
||||
- (NSComparisonResult) compare: (NSGSequence*) aSequence
|
||||
{
|
||||
int i,end;
|
||||
if(![self isNormalized])
|
||||
[self normalize];
|
||||
if(![aSequence isNormalized])
|
||||
[aSequence normalize];
|
||||
if([self length] < [aSequence length])
|
||||
end=[self length];
|
||||
else
|
||||
end=[aSequence length];
|
||||
for (i = 0; i < end; i ++)
|
||||
{
|
||||
if ([self characterAtIndex:i] < [aSequence characterAtIndex:i]) return NSOrderedAscending;
|
||||
if ([self characterAtIndex:i] > [aSequence characterAtIndex:i]) return NSOrderedDescending;
|
||||
}
|
||||
if([self length]<[aSequence length])
|
||||
return NSOrderedAscending;
|
||||
if([self length]>[aSequence length])
|
||||
return NSOrderedDescending;
|
||||
return NSOrderedSame;
|
||||
}
|
||||
|
||||
|
||||
/* NSCopying Protocol */
|
||||
|
||||
- copyWithZone: (NSZone*)zone
|
||||
{
|
||||
return [[[self class] allocWithZone:zone] initWithSequence:self];
|
||||
}
|
||||
|
||||
|
||||
// **************** do I need this?
|
||||
- copy
|
||||
{
|
||||
return [self copyWithZone: NSDefaultMallocZone ()];
|
||||
}
|
||||
|
||||
// **************** do I need this?
|
||||
- mutableCopyWithZone: (NSZone*)zone
|
||||
{
|
||||
return [[[self class] allocWithZone:zone]
|
||||
initWithSequence: self];
|
||||
}
|
||||
|
||||
@end
|
424
Source/NSGString.m
Normal file
424
Source/NSGString.m
Normal file
|
@ -0,0 +1,424 @@
|
|||
/* Implementation for GNUStep of NSStrings with Unicode-string backing
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
|
||||
Written by Stevo Crvenkovski <stevoc@lotus.mpt.com.mk>
|
||||
Date: February 1997
|
||||
|
||||
Based on NSGCSting and NSString
|
||||
Written by: Andrew Kachites McCallum
|
||||
<mccallum@gnu.ai.mit.edu>
|
||||
Date: March 1995
|
||||
|
||||
This file is part of the GNUstep Base 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 <gnustep/base/preface.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <gnustep/base/NSString.h>
|
||||
#include <Foundation/NSGString.h>
|
||||
#include <gnustep/base/NSGString.h>
|
||||
#include <gnustep/base/IndexedCollection.h>
|
||||
#include <gnustep/base/IndexedCollectionPrivate.h>
|
||||
#include <gnustep/base/MallocAddress.h>
|
||||
#include <Foundation/NSValue.h>
|
||||
#include <gnustep/base/behavior.h>
|
||||
#include <gnustep/base/NSGSequence.h>
|
||||
/* memcpy(), strlen(), strcmp() are gcc builtin's */
|
||||
|
||||
#include <gnustep/base/Unicode.h>
|
||||
|
||||
|
||||
@implementation NSGString
|
||||
|
||||
// Initializing Newly Allocated Strings
|
||||
|
||||
/* This is the designated initializer for this class. */
|
||||
- (id) initWithCharactersNoCopy: (unichar*)chars
|
||||
length: (unsigned int)length
|
||||
freeWhenDone: (BOOL)flag
|
||||
{
|
||||
/* assert(!flag); xxx need to make a subclass to handle this. */
|
||||
_count = length;
|
||||
_contents_chars = chars;
|
||||
_free_contents = flag;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithCharacters: (const unichar*)chars
|
||||
length: (unsigned int)length
|
||||
{
|
||||
unichar *s;
|
||||
OBJC_MALLOC(s, unichar, length+1);
|
||||
if (chars)
|
||||
memcpy(s, chars,2*length);
|
||||
s[length] = (unichar)0;
|
||||
return [self initWithCharactersNoCopy:s length:length freeWhenDone:YES];
|
||||
}
|
||||
|
||||
// xxx Folowing two methods should not be in this class.
|
||||
|
||||
// xxx This is not NoCopy.
|
||||
- (id) initWithCStringNoCopy: (char*)byteString
|
||||
length: (unsigned int)length
|
||||
freeWhenDone: (BOOL)flag
|
||||
{ unichar *s;
|
||||
OBJC_MALLOC(s, unichar, length+1);
|
||||
if (byteString)
|
||||
strtoustr(s, byteString, length);
|
||||
s[length] = (unichar)0;
|
||||
return [self initWithCharactersNoCopy:s length:length freeWhenDone:flag];
|
||||
}
|
||||
|
||||
- (id) initWithCString: (const char*)byteString length: (unsigned int)length
|
||||
{
|
||||
unichar *s;
|
||||
// xxx int cnt from strtoustr gets real length !!!
|
||||
OBJC_MALLOC(s, unichar, length+1);
|
||||
if (byteString)
|
||||
strtoustr(s, byteString, length);
|
||||
s[length] = (unichar)0;
|
||||
return [self initWithCharactersNoCopy:s length:length freeWhenDone:YES];
|
||||
}
|
||||
|
||||
// Getting a String's Length
|
||||
|
||||
- (unsigned int) length
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
|
||||
// Accessing Characters
|
||||
|
||||
- (unichar) characterAtIndex: (unsigned int)index
|
||||
{
|
||||
/* xxx This should raise an NSException. */
|
||||
CHECK_INDEX_RANGE_ERROR(index, _count);
|
||||
return _contents_chars[index];
|
||||
}
|
||||
|
||||
// Dividing Strings into Substrings
|
||||
|
||||
- (NSString*) substringFromRange: (NSRange)aRange
|
||||
{
|
||||
if (aRange.location > _count)
|
||||
[NSException raise: NSRangeException format:@"Invalid location."];
|
||||
if (aRange.length > (_count - aRange.location))
|
||||
[NSException raise: NSRangeException format:@"Invalid location+length."];
|
||||
return [[self class] stringWithCharacters: _contents_chars + aRange.location
|
||||
length: aRange.length];
|
||||
}
|
||||
|
||||
// Getting C Strings
|
||||
|
||||
- (const char *) cString
|
||||
{
|
||||
char *r;
|
||||
|
||||
OBJC_MALLOC(r, char, _count+1);
|
||||
ustrtostr(r,_contents_chars, _count);
|
||||
r[_count] = '\0';
|
||||
[[[MallocAddress alloc] initWithAddress:r] autorelease];
|
||||
return r;
|
||||
}
|
||||
|
||||
// xxx fix me
|
||||
- (unsigned int) cStringLength
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
|
||||
// private method for Unicode level 3 implementation
|
||||
- (int) _baseLength
|
||||
{
|
||||
int count=0;
|
||||
int blen=0;
|
||||
while(count < [self length])
|
||||
if(!uni_isnonsp([self characterAtIndex: count++]))
|
||||
blen++;
|
||||
return blen;
|
||||
}
|
||||
|
||||
// #ifndef NO_GNUSTEP
|
||||
|
||||
// xxx This is Not NoCopy
|
||||
// copy of cString just for compatibility
|
||||
// Is this realy needed ???
|
||||
- (const char *) cStringNoCopy
|
||||
{
|
||||
char *r;
|
||||
|
||||
OBJC_MALLOC(r, char, _count+1);
|
||||
ustrtostr(r,_contents_chars, _count);
|
||||
r[_count] = '\0';
|
||||
[[[MallocAddress alloc] initWithAddress:r] autorelease];
|
||||
return r;
|
||||
}
|
||||
// #endif /* NO_GNUSTEP */
|
||||
|
||||
/* NSCoding Protocol */
|
||||
|
||||
- (void) encodeWithCoder: aCoder
|
||||
{
|
||||
[super encodeWithCoder:aCoder]; // *** added this
|
||||
[aCoder encodeValueOfObjCType:@encode(unichar*) at:&_contents_chars
|
||||
withName:@"Concrete String content_chars"];
|
||||
}
|
||||
|
||||
- initWithCoder: aCoder
|
||||
{
|
||||
[super initWithCoder:aCoder];
|
||||
[aCoder decodeValueOfObjCType:@encode(unichar*) at:&_contents_chars
|
||||
withName:NULL];
|
||||
_count = uslen(_contents_chars);
|
||||
_free_contents = YES;
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
// ******* Stuff from NSGCString *********
|
||||
// Do we need this ???
|
||||
|
||||
- (void) _collectionReleaseContents
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
- (void) _collectionDealloc
|
||||
{
|
||||
if (_free_contents)
|
||||
OBJC_FREE(_contents_chars);
|
||||
}
|
||||
|
||||
- (Class) classForConnectedCoder: aRmc
|
||||
{
|
||||
/* Make sure that Connection's always send us bycopy,
|
||||
i.e. as our own class, not a Proxy class. */
|
||||
return [self class];
|
||||
}
|
||||
|
||||
// FOR IndexedCollection SUPPORT;
|
||||
|
||||
- objectAtIndex: (unsigned)index
|
||||
{
|
||||
CHECK_INDEX_RANGE_ERROR(index, _count);
|
||||
return [NSNumber numberWithChar: unitochar(_contents_chars[index])];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@implementation NSGMutableString
|
||||
|
||||
// @class NSMutableString;
|
||||
|
||||
// @protocol NSMutableString <NSString>
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
static int done = 0;
|
||||
if (!done)
|
||||
{
|
||||
done = 1;
|
||||
class_add_behavior(self, [NSGString class]);
|
||||
}
|
||||
}
|
||||
typedef struct {
|
||||
@defs(NSGMutableString)
|
||||
} NSGMutableStringStruct;
|
||||
|
||||
static inline void
|
||||
stringIncrementCountAndMakeHoleAt(NSGMutableStringStruct *self,
|
||||
int index, int size)
|
||||
{
|
||||
#ifndef STABLE_MEMCPY
|
||||
{
|
||||
int i;
|
||||
for (i = self->_count; i >= index; i--)
|
||||
self->_contents_chars[i+size] = self->_contents_chars[i];
|
||||
}
|
||||
#else
|
||||
memcpy(self->_contents_chars + index,
|
||||
self->_contents_chars + index + size,
|
||||
2*(self->_count - index));
|
||||
#endif /* STABLE_MEMCPY */
|
||||
(self->_count) += size;
|
||||
}
|
||||
|
||||
static inline void
|
||||
stringDecrementCountAndFillHoleAt(NSGMutableStringStruct *self,
|
||||
int index, int size)
|
||||
{
|
||||
(self->_count) -= size;
|
||||
#ifndef STABLE_MEMCPY
|
||||
{
|
||||
int i;
|
||||
for (i = index; i <= self->_count; i++)
|
||||
self->_contents_chars[i] = self->_contents_chars[i+size];
|
||||
}
|
||||
#else
|
||||
memcpy(self->_contents_chars + index + size,
|
||||
self->_contents_chars + index,
|
||||
2*(self->_count - index));
|
||||
#endif // STABLE_MEMCPY
|
||||
}
|
||||
|
||||
// Initializing Newly Allocated Strings
|
||||
|
||||
// This is the designated initializer for this class
|
||||
// xxx Should capacity include the '\0' terminator?
|
||||
- initWithCapacity: (unsigned)capacity
|
||||
{
|
||||
_count = 0;
|
||||
_capacity = MAX(capacity, 2);
|
||||
OBJC_MALLOC(_contents_chars, unichar, _capacity);
|
||||
_contents_chars[0] = 0;
|
||||
_free_contents = YES;
|
||||
return self;
|
||||
}
|
||||
|
||||
// Modify A String
|
||||
|
||||
- (void) deleteCharactersInRange: (NSRange)range
|
||||
{
|
||||
stringDecrementCountAndFillHoleAt((NSGMutableStringStruct*)self,
|
||||
range.location, range.length);
|
||||
}
|
||||
|
||||
// xxx Check this
|
||||
- (void) insertString: (NSString*)aString atIndex:(unsigned)index
|
||||
{
|
||||
unsigned c = [aString length];
|
||||
unichar * u;
|
||||
OBJC_MALLOC(u, unichar, c+1);
|
||||
if (_count + c >= _capacity)
|
||||
{
|
||||
_capacity = MAX(_capacity*2, _count+2*c);
|
||||
OBJC_REALLOC(_contents_chars, unichar, _capacity);
|
||||
}
|
||||
stringIncrementCountAndMakeHoleAt((NSGMutableStringStruct*)self, index, c);
|
||||
[aString getCharacters:u];
|
||||
memcpy(_contents_chars + index,u, 2*c);
|
||||
_contents_chars[_count] = 0;
|
||||
}
|
||||
|
||||
|
||||
- (void) setString: (NSString*)aString
|
||||
{
|
||||
int len = [aString length];
|
||||
if (_capacity < len+1)
|
||||
{
|
||||
_capacity = len+1;
|
||||
OBJC_REALLOC(_contents_chars, unichar, _capacity);
|
||||
}
|
||||
[aString getCharacters: _contents_chars];
|
||||
_contents_chars[len] = 0;
|
||||
_count = len;
|
||||
}
|
||||
|
||||
// ************ Stuff from NSGCString *********
|
||||
|
||||
/* xxx This method may be removed in future. */
|
||||
- (void) setCString: (const char *)byteString length: (unsigned)length
|
||||
{
|
||||
if (_capacity < length+1)
|
||||
{
|
||||
_capacity = length+1;
|
||||
OBJC_REALLOC(_contents_chars, unichar, _capacity);
|
||||
}
|
||||
strtoustr(_contents_chars, byteString, length);
|
||||
_contents_chars[length] = 0;
|
||||
_count = length;
|
||||
}
|
||||
|
||||
// xxx This should not be in this class
|
||||
/* Override NSString's designated initializer for CStrings. */
|
||||
- (id) initWithCStringNoCopy: (char*)byteString
|
||||
length: (unsigned int)length
|
||||
freeWhenDone: (BOOL)flag
|
||||
{
|
||||
[self initWithCapacity:length];
|
||||
[self setCString:byteString length:length];
|
||||
return self;
|
||||
}
|
||||
|
||||
/* For IndexedCollecting Protocol and other GNU libobjects conformity. */
|
||||
|
||||
/* xxx This should be made to return void, but we need to change
|
||||
IndexedCollecting and its conformers */
|
||||
- (void) removeRange: (IndexRange)range
|
||||
{
|
||||
stringDecrementCountAndFillHoleAt((NSGMutableStringStruct*)self,
|
||||
range.location, range.length);
|
||||
}
|
||||
|
||||
- (void) encodeWithCoder: aCoder // *** changed to unichar
|
||||
{
|
||||
[aCoder encodeValueOfObjCType:@encode(unsigned) at:&_capacity
|
||||
withName:@"String capacity"];
|
||||
[aCoder encodeValueOfObjCType:@encode(unichar*) at:&_contents_chars
|
||||
withName:@"String content_chars"];
|
||||
}
|
||||
|
||||
- initWithCoder: aCoder // *** changed to unichar
|
||||
{
|
||||
unsigned cap;
|
||||
|
||||
[aCoder decodeValueOfObjCType:@encode(unsigned) at:&cap withName:NULL];
|
||||
[self initWithCapacity:cap];
|
||||
[aCoder decodeValueOfObjCType:@encode(unichar*) at:&_contents_chars
|
||||
withName:NULL];
|
||||
_count = uslen(_contents_chars);
|
||||
_capacity = cap;
|
||||
return self;
|
||||
}
|
||||
|
||||
/* For IndexedCollecting protocol */
|
||||
|
||||
- (char) charAtIndex: (unsigned)index
|
||||
{
|
||||
CHECK_INDEX_RANGE_ERROR(index, _count);
|
||||
return unitochar(_contents_chars[index]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// FOR IndexedCollection and OrderedCollection SUPPORT;
|
||||
|
||||
- (void) insertObject: newObject atIndex: (unsigned)index
|
||||
{
|
||||
CHECK_INDEX_RANGE_ERROR(index, _count+1);
|
||||
// one for the next char, one for the '\0';
|
||||
if (_count+1 >= _capacity)
|
||||
{
|
||||
_capacity *= 2;
|
||||
OBJC_REALLOC(_contents_chars, unichar, _capacity);
|
||||
}
|
||||
stringIncrementCountAndMakeHoleAt((NSGMutableStringStruct*)self, index, 1);
|
||||
_contents_chars[index] = [newObject charValue];
|
||||
_contents_chars[_count] = 0;
|
||||
}
|
||||
|
||||
|
||||
- (void) removeObjectAtIndex: (unsigned)index
|
||||
{
|
||||
CHECK_INDEX_RANGE_ERROR(index, _count);
|
||||
stringDecrementCountAndFillHoleAt((NSGMutableStringStruct*)self, index, 1);
|
||||
_contents_chars[_count] = 0;
|
||||
}
|
||||
|
||||
@end
|
271
Source/Unicode.m
Normal file
271
Source/Unicode.m
Normal file
|
@ -0,0 +1,271 @@
|
|||
/* Support functions for Unicode implementation
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Stevo Crvenkovski <stevoc@lotus.mpt.com.mk>
|
||||
Date: March 1997
|
||||
|
||||
This file is part of the GNUstep Base 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 <Foundation/NSString.h>
|
||||
|
||||
struct _ucc_ {unichar from; char to;};
|
||||
|
||||
#include "unicode/cyrillic.h"
|
||||
#include "unicode/nextstep.h"
|
||||
#include "unicode/caseconv.h"
|
||||
#include "unicode/cop.h"
|
||||
#include "unicode/decomp.h"
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
unichar encode_chartouni(char c, NSStringEncoding enc)
|
||||
{
|
||||
/* All that I could find in Next documentation
|
||||
on NSNonLossyASCIIStringEncoding was <<forthcoming>>. */
|
||||
if((enc==NSNonLossyASCIIStringEncoding)
|
||||
|| (enc==NSASCIIStringEncoding)
|
||||
|| (enc==NSISOLatin1StringEncoding))
|
||||
return (unichar)c;
|
||||
|
||||
if((enc==NSNEXTSTEPStringEncoding))
|
||||
if((unsigned char)c<Next_conv_base)
|
||||
return (unichar)c;
|
||||
else
|
||||
return(Next_char_to_uni_table[(unsigned char)c - Next_conv_base]);
|
||||
|
||||
if((enc==NSCyrillicStringEncoding))
|
||||
if((unsigned char)c<Cyrillic_conv_base)
|
||||
return (unichar)c;
|
||||
else
|
||||
return(Cyrillic_char_to_uni_table[(unsigned char)c - Cyrillic_conv_base]);
|
||||
|
||||
#if 0
|
||||
if((enc==NSSymbolStringEncoding))
|
||||
if((unsigned char)c<Symbol_conv_base)
|
||||
return (unichar)c;
|
||||
else
|
||||
return(Symbol_char_to_uni_table[(unsigned char)c - Symbol_conv_base]);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char encode_unitochar(unichar u, NSStringEncoding enc)
|
||||
{
|
||||
int res;
|
||||
int i=0;
|
||||
|
||||
if((enc==NSNonLossyASCIIStringEncoding)
|
||||
|| (enc==NSASCIIStringEncoding))
|
||||
if(u<128)
|
||||
return (char)u;
|
||||
else
|
||||
return 0;
|
||||
|
||||
|
||||
if((enc==NSISOLatin1StringEncoding))
|
||||
if(u<256)
|
||||
return (char)u;
|
||||
else
|
||||
return 0;
|
||||
|
||||
if((enc== NSNEXTSTEPStringEncoding))
|
||||
if(u<(unichar)Next_conv_base)
|
||||
return (char)u;
|
||||
else
|
||||
{
|
||||
while(((res=u-Next_uni_to_char_table[i++].from)>0) & (i<Next_uni_to_char_table_size));
|
||||
return res?0:Next_uni_to_char_table[--i].to;
|
||||
}
|
||||
|
||||
if((enc==NSCyrillicStringEncoding))
|
||||
if(u<(unichar)Cyrillic_conv_base)
|
||||
return (char)u;
|
||||
else
|
||||
{
|
||||
while(((res=u-Cyrillic_uni_to_char_table[i++].from)>0) & (i<Cyrillic_uni_to_char_table_size));
|
||||
return res?0:Cyrillic_uni_to_char_table[--i].to;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if((enc==NSSymbolStringEncoding))
|
||||
if(u<(unichar)Symbol_conv_base)
|
||||
return (char)u;
|
||||
else
|
||||
{
|
||||
while(((res=u-Symbol_uni_to_char_table[i++].from)>0) & (i<Symbol_uni_to_char_table_size));
|
||||
return res?'*':Symbol_uni_to_char_table[--i].to;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unichar chartouni(char c)
|
||||
{
|
||||
NSStringEncoding enc = [NSString defaultCStringEncoding];
|
||||
return encode_chartouni(c, enc);
|
||||
}
|
||||
|
||||
char unitochar(unichar u)
|
||||
{
|
||||
unsigned char res;
|
||||
NSStringEncoding enc = [NSString defaultCStringEncoding];
|
||||
if((res=encode_unitochar(u, enc)))
|
||||
return res;
|
||||
else
|
||||
return '*';
|
||||
}
|
||||
|
||||
int strtoustr(unichar * u1,const char *s1,int size)
|
||||
{
|
||||
int count;
|
||||
for(count=0;(s1[count]!=0)&(count<size);count++)
|
||||
u1[count]=chartouni(s1[count]);
|
||||
return count;
|
||||
}
|
||||
|
||||
int ustrtostr(char *s2,unichar *u1,int size)
|
||||
{
|
||||
int count;
|
||||
for(count=0;count<size;count++)
|
||||
s2[count]=unitochar(u1[count]);
|
||||
return(count);
|
||||
}
|
||||
|
||||
/* Be carefull if you use this. Unicode arrays returned by
|
||||
-getCharacters methods are not zero terminated */
|
||||
int
|
||||
uslen (unichar *u)
|
||||
{
|
||||
int len = 0;
|
||||
while (u[len] != 0)
|
||||
{
|
||||
if (u[++len] == 0)
|
||||
return len;
|
||||
++len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
unichar uni_tolower(unichar ch)
|
||||
{
|
||||
int res;
|
||||
int count=0;
|
||||
while(((res=ch - t_tolower[count++][0])>0)&(count<t_len_tolower));
|
||||
return res?ch:t_tolower[--count][1];
|
||||
}
|
||||
|
||||
unichar uni_toupper(unichar ch)
|
||||
{
|
||||
int res;
|
||||
int count=0;
|
||||
while(((res=ch - t_toupper[count++][0])>0)&(count<t_len_toupper));
|
||||
return res?ch:t_toupper[--count][1];
|
||||
}
|
||||
|
||||
unsigned char uni_cop(unichar u)
|
||||
{
|
||||
unichar count,first,last,comp;
|
||||
BOOL notfound;
|
||||
|
||||
first = 0;
|
||||
last = uni_cop_table_size;
|
||||
notfound = TRUE;
|
||||
count=0;
|
||||
|
||||
if(u > (unichar)0x0080) // no nonspacing in ascii
|
||||
{
|
||||
while(notfound & (first <= last))
|
||||
{
|
||||
if(!(first==last))
|
||||
{
|
||||
count = (first + last) / 2;
|
||||
comp=uni_cop_table[count].code;
|
||||
if(comp < u)
|
||||
first = count+1;
|
||||
else
|
||||
if(comp > u)
|
||||
last = count-1;
|
||||
else
|
||||
notfound = FALSE;
|
||||
}
|
||||
else /* first==last */
|
||||
{
|
||||
if(u == uni_cop_table[first].code)
|
||||
return uni_cop_table[first].cop;
|
||||
return 0;
|
||||
} /* else */
|
||||
} /* while notfound ...*/
|
||||
return notfound?0:uni_cop_table[count].cop;
|
||||
}
|
||||
else /* u is ascii */
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL uni_isnonsp(unichar u)
|
||||
{
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
// check is uni_cop good for this
|
||||
if(uni_cop(u))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
unichar *uni_is_decomp(unichar u)
|
||||
{
|
||||
unichar count,first,last,comp;
|
||||
BOOL notfound;
|
||||
|
||||
first = 0;
|
||||
last = uni_dec_table_size;
|
||||
notfound = TRUE;
|
||||
count=0;
|
||||
|
||||
if(u > (unichar)0x0080) // no composites in ascii
|
||||
{
|
||||
while(notfound & (first <= last))
|
||||
{
|
||||
if(!(first==last))
|
||||
{
|
||||
count = (first + last) / 2;
|
||||
comp=uni_dec_table[count].code;
|
||||
if(comp < u)
|
||||
first = count+1;
|
||||
else
|
||||
if(comp > u)
|
||||
last = count-1;
|
||||
else
|
||||
notfound = FALSE;
|
||||
}
|
||||
else /* first==last */
|
||||
{
|
||||
if(u == uni_dec_table[first].code)
|
||||
return uni_dec_table[first].decomp;
|
||||
return 0;
|
||||
} /* else */
|
||||
} /* while notfound ...*/
|
||||
return notfound?0:uni_dec_table[count].decomp;
|
||||
}
|
||||
else /* u is ascii */
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue