mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 08:26:27 +00:00
Applied fixes for map table changes.
Also fixes for GSMime set methods git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@13727 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
e7b980cdda
commit
1fcd66117b
10 changed files with 264 additions and 132 deletions
|
@ -1,5 +1,7 @@
|
|||
2002-05-28 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/gnustep/base/GSMime.h: Make set... methods return void.
|
||||
* Source//GSMime.m: Make set... methods return void.
|
||||
* Headers/gnustep/base/GSIMap.h:
|
||||
* Headers/gnustep/base/NSHashTable.h:
|
||||
* Headers/gnustep/base/NSMapTable.h:
|
||||
|
@ -19,6 +21,9 @@
|
|||
Fixed minor problem in patch, and added code to call functions to
|
||||
clean up after hash and map enumerations. Modified cleanup function
|
||||
to clear enumerator ... for memory release on GC system.
|
||||
Rewrote enumeration code so that it maintains the characteristic
|
||||
that objects can safely be removed from maps after being enumerated
|
||||
(this feature is used in several places).
|
||||
*WARNING* This introduces a binary incompatibility in that the size
|
||||
of the map table and hash table enumeration types has grown.
|
||||
If you have binaries which use the NSEnumerateHashTable() or the
|
||||
|
|
|
@ -224,17 +224,18 @@ struct _GSIMapTable {
|
|||
#endif
|
||||
};
|
||||
|
||||
#ifdef GSI_MAP_ENUMERATOR
|
||||
typedef GSI_MAP_ENUMERATOR GSIMapEnumerator_t;
|
||||
#else
|
||||
struct _GSIMapEnumerator {
|
||||
typedef struct _GSIMapEnumerator {
|
||||
GSIMapTable map; /* the map being enumerated. */
|
||||
GSIMapNode node; /* The next node to use. */
|
||||
size_t bucket; /* The next bucket to use. */
|
||||
};
|
||||
} *_GSIE;
|
||||
|
||||
#ifdef GSI_MAP_ENUMERATOR
|
||||
typedef GSI_MAP_ENUMERATOR GSIMapEnumerator_t;
|
||||
#else
|
||||
typedef struct _GSIMapEnumerator GSIMapEnumerator_t;
|
||||
#endif
|
||||
typedef GSIMapEnumerator_t *GSIMapEnumerator;
|
||||
typedef GSIMapEnumerator_t *GSIMapEnumerator;
|
||||
|
||||
static INLINE GSIMapBucket
|
||||
GSIMapPickBucket(unsigned hash, GSIMapBucket buckets, size_t bucketCount)
|
||||
|
@ -309,10 +310,8 @@ GSIMapRemoveNodeFromMap(GSIMapTable map, GSIMapBucket bkt, GSIMapNode node)
|
|||
|
||||
static INLINE void
|
||||
GSIMapRemangleBuckets(GSIMapTable map,
|
||||
GSIMapBucket old_buckets,
|
||||
size_t old_bucketCount,
|
||||
GSIMapBucket new_buckets,
|
||||
size_t new_bucketCount)
|
||||
GSIMapBucket old_buckets, size_t old_bucketCount,
|
||||
GSIMapBucket new_buckets, size_t new_bucketCount)
|
||||
{
|
||||
while (old_bucketCount-- > 0)
|
||||
{
|
||||
|
@ -344,7 +343,9 @@ GSIMapMoreNodes(GSIMapTable map, unsigned required)
|
|||
* the default zone
|
||||
*/
|
||||
if (map->zone == GSAtomicMallocZone())
|
||||
newArray = (GSIMapNode*)NSZoneMalloc(NSDefaultMallocZone(), arraySize);
|
||||
{
|
||||
newArray = (GSIMapNode*)NSZoneMalloc(NSDefaultMallocZone(), arraySize);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
newArray = (GSIMapNode*)NSZoneMalloc(map->zone, arraySize);
|
||||
|
@ -470,7 +471,9 @@ GSIMapNodeForKey(GSIMapTable map, GSIMapKey key)
|
|||
GSIMapNode node;
|
||||
|
||||
if (map->nodeCount == 0)
|
||||
return 0;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
bucket = GSIMapBucketForKey(map, key);
|
||||
node = GSIMapNodeForKeyInBucket(map, bucket, key);
|
||||
return node;
|
||||
|
@ -489,7 +492,9 @@ GSIMapNodeForSimpleKey(GSIMapTable map, GSIMapKey key)
|
|||
GSIMapNode node;
|
||||
|
||||
if (map->nodeCount == 0)
|
||||
return 0;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
bucket = map->buckets + key.uint % map->bucketCount;
|
||||
node = bucket->firstNode;
|
||||
while ((node != 0) && node->key.uint != key.uint)
|
||||
|
@ -513,6 +518,7 @@ GSIMapResize(GSIMapTable map, size_t new_capacity)
|
|||
while (size < new_capacity)
|
||||
{
|
||||
size_t tmp = old;
|
||||
|
||||
old = size;
|
||||
size += tmp;
|
||||
}
|
||||
|
@ -522,7 +528,9 @@ GSIMapResize(GSIMapTable map, size_t new_capacity)
|
|||
* bucket.
|
||||
*/
|
||||
if (size == 8)
|
||||
size++;
|
||||
{
|
||||
size++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a new set of buckets for this map
|
||||
|
@ -559,21 +567,24 @@ GSIMapRightSizeMap(GSIMapTable map, size_t capacity)
|
|||
|
||||
/** Enumerating **/
|
||||
|
||||
/* WARNING: You should not alter a map while an enumeration is
|
||||
* in progress. The results of doing so are reasonably unpremapable.
|
||||
* With that in mind, read the following warnings carefully. But
|
||||
* remember, DON'T MESS WITH A MAP WHILE YOU'RE ENUMERATING IT. */
|
||||
|
||||
/* IMPORTANT WARNING: Enumerators have a wonderous property.
|
||||
* Once a node has been returned by `GSIMapEnumeratorNextNode()', it may be
|
||||
* removed from the map without effecting the rest of the current
|
||||
* enumeration. */
|
||||
|
||||
/* EXTREMELY IMPORTANT WARNING: The purpose of this warning is point
|
||||
* out that, at this time, various (i.e., many) functions depend on
|
||||
* out that, various (i.e., many) functions currently depend on
|
||||
* the behaviour outlined above. So be prepared for some serious
|
||||
* breakage when you go fudging around with these things. */
|
||||
|
||||
/**
|
||||
* Create an return an enumerator for the specified map.<br />
|
||||
* You must call GSIMapEndEnumerator() when you have finished
|
||||
* with the enumerator.<br />
|
||||
* <strong>WARNING</strong> You should not alter a map while an enumeration
|
||||
* is in progress. The results of doing so are reasonably unpredictable.
|
||||
* <br />Remember, DON'T MESS WITH A MAP WHILE YOU'RE ENUMERATING IT.
|
||||
*/
|
||||
static INLINE GSIMapEnumerator_t
|
||||
GSIMapEnumeratorForMap(GSIMapTable map)
|
||||
{
|
||||
|
@ -582,26 +593,77 @@ GSIMapEnumeratorForMap(GSIMapTable map)
|
|||
enumerator.map = map;
|
||||
enumerator.node = 0;
|
||||
enumerator.bucket = 0;
|
||||
/*
|
||||
* Locate next bucket and node to be returned.
|
||||
*/
|
||||
while (enumerator.bucket < map->bucketCount)
|
||||
{
|
||||
enumerator.node = map->buckets[enumerator.bucket].firstNode;
|
||||
if (enumerator.node != 0)
|
||||
{
|
||||
break; // Got first node, and recorded its bucket.
|
||||
}
|
||||
enumerator.bucket++;
|
||||
}
|
||||
|
||||
return enumerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tidies up after map enumeration ... effectively destroys the enumerator.
|
||||
*/
|
||||
static INLINE void
|
||||
GSIMapEndEnumerator(GSIMapEnumerator enumerator)
|
||||
{
|
||||
((_GSIE)enumerator)->map = 0;
|
||||
((_GSIE)enumerator)->node = 0;
|
||||
((_GSIE)enumerator)->bucket = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bucket from which the next node in the enumeration will
|
||||
* come. Once the next node has been enumerated, you can use the
|
||||
* bucket and node to remove the node from the map using the
|
||||
* GSIMapRemoveNodeFromMap() function.
|
||||
*/
|
||||
static INLINE GSIMapBucket
|
||||
GSIMapEnumeratorBucket(GSIMapEnumerator enumerator)
|
||||
{
|
||||
if (((_GSIE)enumerator)->node != 0)
|
||||
{
|
||||
GSIMapTable map = ((_GSIE)enumerator)->map;
|
||||
|
||||
return &((map->buckets)[((_GSIE)enumerator)->bucket]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next node in the map, or a nul pointer if at the end.
|
||||
*/
|
||||
static INLINE GSIMapNode
|
||||
GSIMapEnumeratorNextNode(GSIMapEnumerator enumerator)
|
||||
{
|
||||
GSIMapNode node;
|
||||
int bucketCount = ((GSIMapTable)enumerator->map)->bucketCount;
|
||||
node = enumerator->node;
|
||||
GSIMapNode node = ((_GSIE)enumerator)->node;
|
||||
|
||||
while(!node && enumerator->bucket < bucketCount)
|
||||
{
|
||||
node = (((GSIMapTable)enumerator->map)->buckets[enumerator->bucket]).firstNode;
|
||||
enumerator->bucket++;
|
||||
}
|
||||
if (node != 0)
|
||||
enumerator->node = node->nextInBucket;
|
||||
{
|
||||
GSIMapNode next = node->nextInBucket;
|
||||
|
||||
/* Send back NODE. */
|
||||
if (next == 0)
|
||||
{
|
||||
GSIMapTable map = ((_GSIE)enumerator)->map;
|
||||
size_t bucketCount = map->bucketCount;
|
||||
size_t bucket = ((_GSIE)enumerator)->bucket;
|
||||
|
||||
while (next == 0 && ++bucket < bucketCount)
|
||||
{
|
||||
next = (map->buckets[bucket]).firstNode;
|
||||
}
|
||||
((_GSIE)enumerator)->bucket = bucket;
|
||||
}
|
||||
((_GSIE)enumerator)->node = next;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -699,10 +761,14 @@ GSIMapCleanMap(GSIMapTable map)
|
|||
for (i = 0; i < map->bucketCount; i++)
|
||||
{
|
||||
node = bucket->firstNode;
|
||||
if(prevNode)
|
||||
if (prevNode != 0)
|
||||
{
|
||||
prevNode->nextInBucket = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
startNode = node;
|
||||
}
|
||||
while(node != 0)
|
||||
{
|
||||
GSI_MAP_RELEASE_KEY(map, node->key);
|
||||
|
|
|
@ -86,8 +86,8 @@
|
|||
id content;
|
||||
}
|
||||
|
||||
- (BOOL) addContent: (id)newContent;
|
||||
- (BOOL) addHeader: (GSMimeHeader*)info;
|
||||
- (void) addContent: (id)newContent;
|
||||
- (void) addHeader: (GSMimeHeader*)info;
|
||||
- (NSArray*) allHeaders;
|
||||
- (id) content;
|
||||
- (id) contentByID: (NSString*)key;
|
||||
|
@ -104,12 +104,12 @@
|
|||
- (GSMimeHeader*) headerNamed: (NSString*)name;
|
||||
- (NSArray*) headersNamed: (NSString*)name;
|
||||
- (GSMimeHeader*) makeContentID;
|
||||
- (BOOL) setContent: (id)newContent;
|
||||
- (BOOL) setContent: (id)newContent
|
||||
- (void) setContent: (id)newContent;
|
||||
- (void) setContent: (id)newContent
|
||||
type: (NSString*)type
|
||||
subType: (NSString*)subType
|
||||
name: (NSString*)name;
|
||||
- (BOOL) setHeader: (GSMimeHeader*)info;
|
||||
- (void) setHeader: (GSMimeHeader*)info;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -57,7 +57,8 @@ static unsigned _count = 0;
|
|||
|
||||
static NSString *makeUniqueString();
|
||||
|
||||
static NSCharacterSet *specials = nil;
|
||||
static NSCharacterSet *rfc822specials = nil;
|
||||
static NSCharacterSet *rfc2045specials = nil;
|
||||
|
||||
/*
|
||||
* Name - decodebase64()
|
||||
|
@ -354,6 +355,7 @@ parseCharacterSet(NSString *token)
|
|||
- (BOOL) _decodeBody: (NSData*)data;
|
||||
- (NSString*) _decodeHeader;
|
||||
- (BOOL) _unfoldHeader;
|
||||
- (BOOL) _scanHeaderParameters: (NSScanner*)scanner into: (GSMimeHeader*)info;
|
||||
@end
|
||||
|
||||
/**
|
||||
|
@ -530,7 +532,8 @@ parseCharacterSet(NSString *token)
|
|||
if (dData == nil || [con isKindOfClass: [GSMimeCodingContext class]] == NO)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Bad destination data for decode"];
|
||||
format: @"[%@ -%@:] bad destination data for decode",
|
||||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||||
}
|
||||
GS_RANGE_CHECK(aRange, len);
|
||||
|
||||
|
@ -1332,42 +1335,11 @@ parseCharacterSet(NSString *token)
|
|||
[document deleteHeaderNamed: name]; // Should be unique
|
||||
}
|
||||
|
||||
return [document addHeader: info];
|
||||
}
|
||||
|
||||
- (BOOL) scanHeaderParameters: (NSScanner*)scanner into: (GSMimeHeader*)info
|
||||
{
|
||||
[self scanPastSpace: scanner];
|
||||
while ([scanner scanString: @";" intoString: 0] == YES)
|
||||
{
|
||||
NSString *paramName;
|
||||
|
||||
paramName = [self scanToken: scanner];
|
||||
if ([paramName length] == 0)
|
||||
{
|
||||
NSLog(@"Invalid Mime %@ field (parameter name)", [info name]);
|
||||
return NO;
|
||||
}
|
||||
[self scanPastSpace: scanner];
|
||||
if ([scanner scanString: @"=" intoString: 0] == YES)
|
||||
{
|
||||
NSString *paramValue;
|
||||
|
||||
[self scanPastSpace: scanner];
|
||||
paramValue = [self scanToken: scanner];
|
||||
[self scanPastSpace: scanner];
|
||||
if (paramValue == nil)
|
||||
{
|
||||
paramValue = @"";
|
||||
}
|
||||
[info setParameter: paramValue forKey: paramName];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Ignoring Mime %@ field parameter (%@)",
|
||||
[info name], paramName);
|
||||
}
|
||||
}
|
||||
NS_DURING
|
||||
[document addHeader: info];
|
||||
NS_HANDLER
|
||||
return NO;
|
||||
NS_ENDHANDLER
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
@ -1556,7 +1528,7 @@ parseCharacterSet(NSString *token)
|
|||
value = type;
|
||||
}
|
||||
|
||||
[self scanHeaderParameters: scanner into: info];
|
||||
[self _scanHeaderParameters: scanner into: info];
|
||||
}
|
||||
else if ([name isEqualToString: @"content-disposition"] == YES)
|
||||
{
|
||||
|
@ -1579,7 +1551,7 @@ parseCharacterSet(NSString *token)
|
|||
/*
|
||||
* Expect anything else to be 'name=value' parameters.
|
||||
*/
|
||||
[self scanHeaderParameters: scanner into: info];
|
||||
[self _scanHeaderParameters: scanner into: info];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1625,11 +1597,20 @@ parseCharacterSet(NSString *token)
|
|||
*/
|
||||
- (NSString*) scanSpecial: (NSScanner*)scanner
|
||||
{
|
||||
NSCharacterSet *specials;
|
||||
unsigned location;
|
||||
unichar c;
|
||||
|
||||
[self scanPastSpace: scanner];
|
||||
|
||||
if (isHttp == YES)
|
||||
{
|
||||
specials = rfc822specials;
|
||||
}
|
||||
else
|
||||
{
|
||||
specials = rfc2045specials;
|
||||
}
|
||||
/*
|
||||
* Now return token delimiter (may be whitespace)
|
||||
*/
|
||||
|
@ -1732,9 +1713,19 @@ parseCharacterSet(NSString *token)
|
|||
}
|
||||
else // Token
|
||||
{
|
||||
NSCharacterSet *specials;
|
||||
NSCharacterSet *skip;
|
||||
NSString *value;
|
||||
|
||||
if (isHttp == YES)
|
||||
{
|
||||
specials = rfc822specials;
|
||||
}
|
||||
else
|
||||
{
|
||||
specials = rfc2045specials;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move past white space.
|
||||
*/
|
||||
|
@ -2289,6 +2280,43 @@ parseCharacterSet(NSString *token)
|
|||
input, dataEnd, lineStart, dataEnd - input, dataEnd - input, &bytes[input]);
|
||||
return unwrappingComplete;
|
||||
}
|
||||
|
||||
- (BOOL) _scanHeaderParameters: (NSScanner*)scanner into: (GSMimeHeader*)info
|
||||
{
|
||||
[self scanPastSpace: scanner];
|
||||
while ([scanner scanString: @";" intoString: 0] == YES)
|
||||
{
|
||||
NSString *paramName;
|
||||
|
||||
paramName = [self scanToken: scanner];
|
||||
if ([paramName length] == 0)
|
||||
{
|
||||
NSLog(@"Invalid Mime %@ field (parameter name)", [info name]);
|
||||
return NO;
|
||||
}
|
||||
[self scanPastSpace: scanner];
|
||||
if ([scanner scanString: @"=" intoString: 0] == YES)
|
||||
{
|
||||
NSString *paramValue;
|
||||
|
||||
[self scanPastSpace: scanner];
|
||||
paramValue = [self scanToken: scanner];
|
||||
[self scanPastSpace: scanner];
|
||||
if (paramValue == nil)
|
||||
{
|
||||
paramValue = @"";
|
||||
}
|
||||
[info setParameter: paramValue forKey: paramName];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"Ignoring Mime %@ field parameter (%@)",
|
||||
[info name], paramName);
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -2630,24 +2658,27 @@ static NSCharacterSet *tokenSet = nil;
|
|||
|
||||
[m formUnionWithCharacterSet:
|
||||
[NSCharacterSet characterSetWithCharactersInString:
|
||||
@"()<>@,;:/[]?=\"\\"]];
|
||||
@".()<>@,;:[]\"\\"]];
|
||||
[m formUnionWithCharacterSet:
|
||||
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
[m formUnionWithCharacterSet:
|
||||
[NSCharacterSet controlCharacterSet]];
|
||||
[m formUnionWithCharacterSet:
|
||||
[NSCharacterSet illegalCharacterSet]];
|
||||
specials = [m copy];
|
||||
rfc822specials = [m copy];
|
||||
[m formUnionWithCharacterSet:
|
||||
[NSCharacterSet characterSetWithCharactersInString:
|
||||
@"/?="]];
|
||||
[m removeCharactersInString: @"."];
|
||||
rfc2045specials = [m copy];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a part to a multipart document
|
||||
*/
|
||||
- (BOOL) addContent: (GSMimeDocument*)newContent
|
||||
- (void) addContent: (GSMimeDocument*)newContent
|
||||
{
|
||||
BOOL result = YES;
|
||||
|
||||
if (content == nil)
|
||||
{
|
||||
content = [NSMutableArray new];
|
||||
|
@ -2658,9 +2689,10 @@ static NSCharacterSet *tokenSet = nil;
|
|||
}
|
||||
else
|
||||
{
|
||||
result = NO;
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"[%@ -%@:] passed bad content",
|
||||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2670,17 +2702,17 @@ static NSCharacterSet *tokenSet = nil;
|
|||
* at least the fields that are standard for all headers.
|
||||
* </p>
|
||||
*/
|
||||
- (BOOL) addHeader: (GSMimeHeader*)info
|
||||
- (void) addHeader: (GSMimeHeader*)info
|
||||
{
|
||||
NSString *name = [info name];
|
||||
|
||||
if (name == nil || [name isEqual: @"unknown"] == YES)
|
||||
{
|
||||
NSLog(@"setHeader: supplied with header without valid name");
|
||||
return NO;
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"[%@ -%@:] header with invalid name",
|
||||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||||
}
|
||||
[headers addObject: info];
|
||||
return YES;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3003,10 +3035,8 @@ static NSCharacterSet *tokenSet = nil;
|
|||
/**
|
||||
* Sets a new value for the content of the document.
|
||||
*/
|
||||
- (BOOL) setContent: (id)newContent
|
||||
- (void) setContent: (id)newContent
|
||||
{
|
||||
BOOL result = YES;
|
||||
|
||||
if ([newContent isKindOfClass: [NSString class]] == YES)
|
||||
{
|
||||
ASSIGNCOPY(content, newContent);
|
||||
|
@ -3023,47 +3053,43 @@ static NSCharacterSet *tokenSet = nil;
|
|||
}
|
||||
else
|
||||
{
|
||||
result = NO;
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"[%@ -%@:] passed bad content",
|
||||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to set the content of the document along with
|
||||
* creating a content-type header for it.
|
||||
*/
|
||||
- (BOOL) setContent: (id)newContent
|
||||
- (void) setContent: (id)newContent
|
||||
type: (NSString*)type
|
||||
subType: (NSString*)subType
|
||||
name: (NSString*)name
|
||||
{
|
||||
GSMimeHeader *hdr;
|
||||
NSString *val;
|
||||
|
||||
if ([type isEqualToString: @"multi-part"] == NO
|
||||
&& [content isKindOfClass: [NSArray class]] == YES)
|
||||
{
|
||||
NSLog(@"Can't set non-'multi-part' content type for array of content");
|
||||
return NO;
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"[%@ -%@:] content doesn't match content-type",
|
||||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||||
}
|
||||
|
||||
if ([self setContent: newContent] == NO)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
GSMimeHeader *hdr;
|
||||
NSString *val;
|
||||
[self setContent: newContent];
|
||||
|
||||
val = [NSString stringWithFormat: @"%@/%@", type, subType];
|
||||
hdr = [GSMimeHeader alloc];
|
||||
hdr = [hdr initWithName: @"content-type" value: val parameters: nil];
|
||||
if (name != nil)
|
||||
{
|
||||
[hdr setParameter: name forKey: @"name"];
|
||||
}
|
||||
[self setHeader: hdr];
|
||||
RELEASE(hdr);
|
||||
val = [NSString stringWithFormat: @"%@/%@", type, subType];
|
||||
hdr = [GSMimeHeader alloc];
|
||||
hdr = [hdr initWithName: @"content-type" value: val parameters: nil];
|
||||
if (name != nil)
|
||||
{
|
||||
[hdr setParameter: name forKey: @"name"];
|
||||
}
|
||||
return YES;
|
||||
[self setHeader: hdr];
|
||||
RELEASE(hdr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3071,7 +3097,7 @@ static NSCharacterSet *tokenSet = nil;
|
|||
* Any other headers with the same name will be removed from
|
||||
* the document.
|
||||
*/
|
||||
- (BOOL) setHeader: (GSMimeHeader*)info
|
||||
- (void) setHeader: (GSMimeHeader*)info
|
||||
{
|
||||
NSString *name = [info name];
|
||||
|
||||
|
@ -3092,7 +3118,7 @@ static NSCharacterSet *tokenSet = nil;
|
|||
}
|
||||
}
|
||||
}
|
||||
return [self addHeader: info];
|
||||
[self addHeader: info];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
RELEASE(set);
|
||||
[super dealloc];
|
||||
}
|
||||
|
@ -160,6 +161,7 @@
|
|||
(*imp2)(aCoder, sel2, type, &node->value.uint);
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
}
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
}
|
||||
|
||||
- (unsigned) hash
|
||||
|
@ -249,27 +251,32 @@
|
|||
NSDefaultMallocZone()] initWithSet: self]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all objcts which have not been added more than level times
|
||||
* from the counted set.<br />
|
||||
* Note to GNUstep maintainers ... this method depends on the characteristic
|
||||
* of the GSIMap enumeration that, once enumerated, an object can be removed
|
||||
* from the map. If GSIMap ever loses that characterstic, this will break.
|
||||
*/
|
||||
- (void) purge: (int)level
|
||||
{
|
||||
if (level > 0)
|
||||
{
|
||||
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
|
||||
GSIMapBucket bucket = GSIMapEnumeratorBucket(&enumerator);
|
||||
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
|
||||
while (node != 0)
|
||||
{
|
||||
GSIMapNode next = GSIMapEnumeratorNextNode(&enumerator);
|
||||
|
||||
if (node->value.uint <= level)
|
||||
{
|
||||
GSIMapBucket bucket;
|
||||
|
||||
bucket = GSIMapBucketForKey(&map, node->key);
|
||||
GSIMapRemoveNodeFromMap(&map, bucket, node);
|
||||
GSIMapFreeNode(&map, node);
|
||||
}
|
||||
node = next;
|
||||
bucket = GSIMapEnumeratorBucket(&enumerator);
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
}
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ static SEL objSel;
|
|||
(*imp)(aCoder, sel, node->value.obj);
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
}
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
}
|
||||
|
||||
- (unsigned) hash
|
||||
|
@ -350,6 +351,7 @@ static SEL objSel;
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
RELEASE(dictionary);
|
||||
[super dealloc];
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
RELEASE(set);
|
||||
[super dealloc];
|
||||
}
|
||||
|
@ -121,6 +122,7 @@ static Class mutableSetClass;
|
|||
objs[i++] = node->key.obj;
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
}
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
return AUTORELEASE([[arrayClass allocWithZone: NSDefaultMallocZone()]
|
||||
initWithObjects: objs count: i]);
|
||||
}
|
||||
|
@ -167,6 +169,7 @@ static Class mutableSetClass;
|
|||
(*imp)(aCoder, sel, node->key.obj);
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
}
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
}
|
||||
|
||||
- (unsigned) hash
|
||||
|
@ -247,10 +250,12 @@ static Class mutableSetClass;
|
|||
{
|
||||
if (GSIMapNodeForKey(&map, node->key) != 0)
|
||||
{
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
return YES;
|
||||
}
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
}
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -295,9 +300,11 @@ static Class mutableSetClass;
|
|||
else
|
||||
{
|
||||
// 1.2 if false -> return NO;
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
// 2. return YES; all members in this set are also in the otherSet.
|
||||
return YES;
|
||||
}
|
||||
|
@ -334,10 +341,12 @@ static Class mutableSetClass;
|
|||
{
|
||||
if (GSIMapNodeForKey(&(((GSSet*)other)->map), node->key) == 0)
|
||||
{
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
return NO;
|
||||
}
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
}
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -358,10 +367,12 @@ static Class mutableSetClass;
|
|||
{
|
||||
if ([other member: node->key.obj] == nil)
|
||||
{
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
return NO;
|
||||
}
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
}
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
|
@ -378,6 +389,7 @@ static Class mutableSetClass;
|
|||
[node->key.obj performSelector: aSelector];
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
}
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
}
|
||||
|
||||
- (void) makeObjectsPerformSelector: (SEL)aSelector
|
||||
|
@ -390,6 +402,7 @@ static Class mutableSetClass;
|
|||
[node->key.obj performSelector: aSelector];
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
}
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
}
|
||||
|
||||
- (void) makeObjectsPerformSelector: (SEL)aSelector withObject: argument
|
||||
|
@ -402,6 +415,7 @@ static Class mutableSetClass;
|
|||
[node->key.obj performSelector: aSelector withObject: argument];
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
}
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
}
|
||||
|
||||
- (void) makeObjectsPerform: (SEL)aSelector withObject: argument
|
||||
|
@ -414,6 +428,7 @@ static Class mutableSetClass;
|
|||
[node->key.obj performSelector: aSelector withObject: argument];
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
}
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
}
|
||||
|
||||
- (id) member: (id)anObject
|
||||
|
@ -529,18 +544,21 @@ static Class mutableSetClass;
|
|||
if (other != self)
|
||||
{
|
||||
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
|
||||
GSIMapBucket bucket = GSIMapEnumeratorBucket(&enumerator);
|
||||
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
|
||||
while (node != 0)
|
||||
{
|
||||
GSIMapNode next = GSIMapEnumeratorNextNode(&enumerator);
|
||||
|
||||
if ([other containsObject: node->key.obj] == NO)
|
||||
{
|
||||
GSIMapRemoveKey(&map, node->key);
|
||||
GSIMapRemoveNodeFromMap(&map, bucket, node);
|
||||
GSIMapFreeNode(&map, node);
|
||||
}
|
||||
node = next;
|
||||
bucket = GSIMapEnumeratorBucket(&enumerator);
|
||||
node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
}
|
||||
GSIMapEndEnumerator(&enumerator);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -194,6 +194,7 @@ $(GNUSTEP_OBJ_DIR)/NSUnarchiver.o \
|
|||
#
|
||||
# Files that include GSIArray.h will need a rebuild if it is changed.
|
||||
#
|
||||
$(GNUSTEP_OBJ_DIR)/NSFileManager.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSNotificationCenter.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSPortCoder.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSRunLoop.o \
|
||||
|
@ -204,13 +205,17 @@ $(GNUSTEP_OBJ_DIR)/NSUnarchiver.o \
|
|||
#
|
||||
# Files that include GSIMap.h will need a rebuild if it is changed.
|
||||
#
|
||||
$(GNUSTEP_OBJ_DIR)/GSAttributedString.o \
|
||||
$(GNUSTEP_OBJ_DIR)/GSCountedSet.o \
|
||||
$(GNUSTEP_OBJ_DIR)/GSDictionary.o \
|
||||
$(GNUSTEP_OBJ_DIR)/GSFFCallInvocation.o \
|
||||
$(GNUSTEP_OBJ_DIR)/GSSet.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSArchiver.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSConnection.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSGAttributedString.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSGDictionary.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSHashTable.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSMapTable.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSNotificationCenter.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSObject.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSPortCoder.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSSerializer.o \
|
||||
: $(HEADER_DIR)/GSIMap.h $(HEADER_DIR)/GSUnion.h
|
||||
|
|
|
@ -128,9 +128,11 @@ NSCompareHashTables(NSHashTable *table1, NSHashTable *table2)
|
|||
{
|
||||
if (GSIMapNodeForKey(t2, n->key) == 0)
|
||||
{
|
||||
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
@ -159,6 +161,7 @@ NSCopyHashTableWithZone(NSHashTable *table, NSZone *zone)
|
|||
{
|
||||
GSIMapAddKey(t, n->key);
|
||||
}
|
||||
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
|
||||
|
||||
return (NSHashTable*)t;
|
||||
}
|
||||
|
@ -234,9 +237,7 @@ NSEndHashTableEnumeration(NSHashEnumerator *enumerator)
|
|||
NSWarnFLog(@"Nul enumerator argument supplied");
|
||||
return;
|
||||
}
|
||||
#if GS_WITH_GC
|
||||
memset(enumerator, 0, sizeof(*enumerator));
|
||||
#endif
|
||||
GSIMapEndEnumerator((GSIMapEnumerator)enumerator);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -173,13 +173,16 @@ NSCompareMapTables(NSMapTable *table1, NSMapTable *table2)
|
|||
{
|
||||
NSMapEnumerator enumerator = GSIMapEnumeratorForMap((GSIMapTable)t1);
|
||||
GSIMapNode n;
|
||||
|
||||
while ((n = GSIMapEnumeratorNextNode(&enumerator)) != 0)
|
||||
{
|
||||
if (GSIMapNodeForKey(t2, n->key) == 0)
|
||||
{
|
||||
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
@ -209,6 +212,7 @@ NSCopyMapTableWithZone(NSMapTable *table, NSZone *zone)
|
|||
{
|
||||
GSIMapAddPair(t, n->key, n->value);
|
||||
}
|
||||
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
|
||||
|
||||
return (NSMapTable*)t;
|
||||
}
|
||||
|
@ -295,9 +299,7 @@ NSEndMapTableEnumeration(NSMapEnumerator *enumerator)
|
|||
NSWarnFLog(@"Nul enumerator argument supplied");
|
||||
return;
|
||||
}
|
||||
#if GS_WITH_GC
|
||||
memset(enumerator, 0, sizeof(*enumerator));
|
||||
#endif
|
||||
GSIMapEndEnumerator((GSIMapEnumerator)enumerator);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue