mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 00:41:02 +00:00
commit
e23ab3b394
41 changed files with 1281 additions and 827 deletions
24
ANNOUNCE
24
ANNOUNCE
|
@ -169,7 +169,29 @@ methods.
|
|||
The gnustep-base-1.27.0.tar.gz distribution file has been placed at
|
||||
<ftp://ftp.gnustep.org/pub/gnustep/core>.
|
||||
|
||||
Please log bug reports on the GNUstep project page
|
||||
It is accompanied by gnustep-base-1.27.0.tar.gz.sig, a PGP signature
|
||||
which you can validate by putting both files in the same directory and
|
||||
using:
|
||||
|
||||
gpg --verify gnustep-base-1.27.0.tar.gz.sig
|
||||
|
||||
Signature has been created using the key with the following
|
||||
fingerprint:
|
||||
|
||||
83AA E47C E829 A414 6EF8 3420 CA86 8D4C 9914 9679
|
||||
|
||||
Read the INSTALL file or the GNUstep-HOWTO for installation
|
||||
instructions.
|
||||
|
||||
1.4 Where do I send bug reports?
|
||||
================================
|
||||
|
||||
Please log bug reports on the GNUstep project page
|
||||
<http://savannah.gnu.org/bugs/?group=gnustep> or send bug reports to
|
||||
<bug-gnustep@gnu.org>.
|
||||
|
||||
1.5 Obtaining GNUstep Software
|
||||
==============================
|
||||
|
||||
Check out the GNUstep web site. (<http://www.gnustep.org/>) and the GNU
|
||||
web site. (<http://www.gnu.org/>)
|
||||
|
|
69
ChangeLog
69
ChangeLog
|
@ -1,3 +1,72 @@
|
|||
2020-04-26 Fred Kiefer <fredkiefer@gmx.de>
|
||||
|
||||
* Source/NSLocale.m: Respect NSLocaleCalendarIdentifier if
|
||||
NSLocaleCalendar isn't set.
|
||||
* Headers/Foundation/NSCalendar.h,
|
||||
* Source/NSCalendar.m: Add newer features for NSDateComponents and
|
||||
started to clean up NSCalendar implementation.
|
||||
* Tests/base/NSCalendar/features-10-7.m: Add test for different
|
||||
time zone.
|
||||
|
||||
2020-04-21 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSNotification.m:
|
||||
Override -hash and -isEqual: so that notifications with the name name,
|
||||
object, and userInfo are considered equal. This is the OSX behavior.
|
||||
|
||||
2020-04-14 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/GNUstepBase/GSConfig.h.in:
|
||||
* Headers/GNUstepBase/GSVersionMacros.h:
|
||||
* configure.ac:
|
||||
* configure:
|
||||
Remove last vestiges of MIXED ABI support (it didn't really work), and
|
||||
change code to assume that use of the apple runtime means we have the
|
||||
nonfragile ABI (true for modern apple systems we may be interested in
|
||||
using). Regenerate configure script.
|
||||
|
||||
2020-04-13 Ivan Vucica <ivan@vucica.net>
|
||||
|
||||
* Documentation/announce.texi:
|
||||
* ANNOUNCE:
|
||||
Normalize the accompanying text for the release announcement across
|
||||
core packages: standardize chapter name and GPG information.
|
||||
|
||||
2020-04-13 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/Foundation/NSURLProtocol.h:
|
||||
* Source/NSURLProtocol.m:
|
||||
Fix [NSURLProtocol -initWithRequest:cachedResponse:client:] to retain
|
||||
the client (up until the last message is sent to it) as OSX does.
|
||||
|
||||
2020-04-12 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* CharSets/URLFragmentAllowedCharSet.h:
|
||||
* CharSets/URLHostAllowedCharSet.h:
|
||||
* CharSets/URLPasswordAllowedCharSet.h:
|
||||
* CharSets/URLPathAllowedCharSet.h:
|
||||
* CharSets/URLQueryAllowedCharSet.h:
|
||||
* CharSets/URLUserAllowedCharSet.h:
|
||||
Removed character set data headers from non-standard location.
|
||||
* NSCharacterSet.m:
|
||||
Fixed to load URL characterset data from standard file.
|
||||
Changed bitmap representation to use much less space for charsets
|
||||
residing wholly in the base plane (in particular the URL charsets
|
||||
which are purely ASCII characters).
|
||||
* NSCharacterSetData.h:
|
||||
Regenerated to contain the URL charactersets and to contain the
|
||||
latest Unicode data (3rd Oct 2019).
|
||||
|
||||
2020-04-10 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/GNUstepBase/GNUstep.h:
|
||||
Add ASSIGNMUTABLECOPY() macro for consistency with ASSIGNCOPY()
|
||||
Wolfgang pointed out that the lack of this macro was uninutitive.
|
||||
|
||||
2020-04-07 Frederik Seiffert <frederik@algoriddim.com>
|
||||
|
||||
* Source/NSOperation.m: Fix completion block memory management.
|
||||
|
||||
2020-04-05 Ivan Vucica <ivan@vucica.net>
|
||||
|
||||
* ANNOUNCE:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
@c -*- texinfo -*-
|
||||
@chapter Announcement
|
||||
|
||||
@c set the vars GNUSTEP-BASE-VERSION and GNUSTEP-BASE-GCC-VERSION
|
||||
|
@ -31,9 +32,31 @@ at @samp{http://www.gnustep.org}.
|
|||
@ifset GNUSTEP-BASE-FTP-MACHINE
|
||||
The gnustep-base-@value{GNUSTEP-BASE-VERSION}.tar.gz distribution file has
|
||||
been placed at @url{ftp://@value{GNUSTEP-BASE-FTP-MACHINE}/@value{GNUSTEP-BASE-FTP-DIRECTORY}}.
|
||||
|
||||
It is accompanied by gnustep-base-@value{GNUSTEP-BASE-VERSION}.tar.gz.sig, a
|
||||
PGP signature which you can validate by putting both files in the same
|
||||
directory and using:
|
||||
|
||||
@example
|
||||
gpg --verify gnustep-base-@value{GNUSTEP-BASE-VERSION}.tar.gz.sig
|
||||
@end example
|
||||
|
||||
Signature has been created using the key with the following fingerprint:
|
||||
|
||||
@example
|
||||
83AA E47C E829 A414 6EF8 3420 CA86 8D4C 9914 9679
|
||||
@end example
|
||||
@end ifset
|
||||
|
||||
Read the INSTALL file or the GNUstep-HOWTO for installation instructions.
|
||||
|
||||
@section Where do I send bug reports?
|
||||
|
||||
Please log bug reports on the GNUstep project page
|
||||
@url{http://savannah.gnu.org/bugs/?group=gnustep} or send bug
|
||||
reports to @email{bug-gnustep@@gnu.org}.
|
||||
|
||||
@section Obtaining GNUstep Software
|
||||
|
||||
Check out the GNUstep web site. (@url{http://www.gnustep.org/}) and the
|
||||
GNU web site. (@url{http://www.gnu.org/})
|
||||
|
|
|
@ -129,7 +129,7 @@ enum
|
|||
NSCalendarUnitWeekOfMonth = (1UL << 12),
|
||||
NSCalendarUnitWeekOfYear = (1UL << 13),
|
||||
NSCalendarUnitYearForWeekOfYear = (1UL << 14),
|
||||
NSCalendarUnitNanosecond = (1 << 15), // FIXME: unimplemented
|
||||
NSCalendarUnitNanosecond = (1 << 15),
|
||||
NSCalendarUnitCalendar = (1 << 20), // FIXME: unimplemented
|
||||
NSCalendarUnitTimeZone = (1 << 21) // FIXME: unimplemented
|
||||
#endif
|
||||
|
@ -227,6 +227,7 @@ enum
|
|||
* yearForWeekOfYear is 2013, since it's already week 1 in 2013.
|
||||
*/
|
||||
- (NSInteger) yearForWeekOfYear;
|
||||
- (NSInteger) nanosecond;
|
||||
|
||||
/** Sets the number of the week in this month. */
|
||||
- (void) setWeekOfMonth: (NSInteger) v;
|
||||
|
@ -241,8 +242,22 @@ enum
|
|||
* See the explanation at <code>-yearForWeekOfYear</code>.
|
||||
*/
|
||||
- (void) setYearForWeekOfYear: (NSInteger) v;
|
||||
- (void) setNanosecond: (NSInteger) v;
|
||||
|
||||
#endif
|
||||
|
||||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_8, GS_API_LATEST)
|
||||
- (BOOL) leapMonth;
|
||||
- (void) setLeapMonth: (BOOL) v;
|
||||
#endif
|
||||
|
||||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_9, GS_API_LATEST)
|
||||
- (BOOL) isValidDate;
|
||||
- (BOOL) isValidDateInCalendar: (NSCalendar *) calendar;
|
||||
- (NSInteger) valueForComponent: (NSCalendarUnit) unit;
|
||||
- (void) setValue: (NSInteger) value
|
||||
forComponent: (NSCalendarUnit) unit;
|
||||
#endif
|
||||
@end
|
||||
|
||||
|
||||
|
|
|
@ -171,7 +171,8 @@ extern "C" {
|
|||
* The cachedResponse may be the result of a previous load of the
|
||||
* request (in which case the protocol may validate and use it).<br />
|
||||
* The client is the object which receives messages about the progress
|
||||
* of the load.
|
||||
* of the load. This is retained by the protocl instance and is released
|
||||
* once the last message has been sent to it.
|
||||
*/
|
||||
- (id) initWithRequest: (NSURLRequest *)request
|
||||
cachedResponse: (NSCachedURLResponse *)cachedResponse
|
||||
|
|
|
@ -80,6 +80,9 @@
|
|||
#ifndef ASSIGNCOPY
|
||||
#define ASSIGNCOPY(object,value) object = [(value) copy]
|
||||
#endif
|
||||
#ifndef ASSIGNMUTABLECOPY
|
||||
#define ASSIGNMUTABLECOPY(object,value) object = [(value) mutableCopy]
|
||||
#endif
|
||||
#ifndef DESTROY
|
||||
#define DESTROY(object) object = nil
|
||||
#endif
|
||||
|
@ -180,6 +183,19 @@ id __object = (object); (__object != nil) ? [__object autorelease] : nil; })
|
|||
})
|
||||
#endif
|
||||
|
||||
#ifndef ASSIGNMUTABLECOPY
|
||||
/**
|
||||
* ASSIGNMUTABLECOPY(object,value) assigns a mutable copy of the value
|
||||
* to the object with release of the original.<br />
|
||||
* Use this to avoid retain/release errors.
|
||||
*/
|
||||
#define ASSIGNMUTABLECOPY(object,value) ({\
|
||||
id __object = object; \
|
||||
object = [(value) mutableCopy];\
|
||||
[__object release]; \
|
||||
})
|
||||
#endif
|
||||
|
||||
#ifndef DESTROY
|
||||
/**
|
||||
* DESTROY() is a release operation which also sets the variable to be
|
||||
|
|
|
@ -262,7 +262,6 @@ typedef struct {
|
|||
#define OBJC2RUNTIME @OBJC2RUNTIME@
|
||||
#define BASE_NATIVE_OBJC_EXCEPTIONS @BASE_NATIVE_OBJC_EXCEPTIONS@
|
||||
#define GS_NONFRAGILE @GS_NONFRAGILE@
|
||||
#define GS_MIXEDABI @GS_MIXEDABI@
|
||||
#define GS_USE_LIBXML @HAVE_LIBXML@
|
||||
#define GS_USE_GNUTLS @HAVE_GNUTLS@
|
||||
#define GS_USE_AVAHI @HAVE_AVAHI@
|
||||
|
|
|
@ -283,20 +283,15 @@
|
|||
* in the class source itsself
|
||||
*/
|
||||
|
||||
#if GS_MIXEDABI
|
||||
# undef GS_NONFRAGILE
|
||||
# define GS_NONFRAGILE 0 /* Mixed is treated as fragile */
|
||||
#if (__has_feature(objc_nonfragile_abi))
|
||||
# if !GS_NONFRAGILE
|
||||
# if defined(GNUSTEP_BASE_INTERNAL)
|
||||
# error "You are building gnustep-base using the objc-nonfragile-abi but your gnustep-base was not configured to use it."
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
# if (__has_feature(objc_nonfragile_abi))
|
||||
# if !GS_NONFRAGILE
|
||||
# if defined(GNUSTEP_BASE_INTERNAL)
|
||||
# error "You are building gnustep-base using the objc-nonfragile-abi but your gnustep-base was not configured to use it."
|
||||
# endif
|
||||
# endif
|
||||
# else
|
||||
# if GS_NONFRAGILE
|
||||
# error "Your gnustep-base was configured for the objc-nonfragile-abi but you are not using it now."
|
||||
# endif
|
||||
# if GS_NONFRAGILE
|
||||
# error "Your gnustep-base was configured for the objc-nonfragile-abi but you are not using it now."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -115,7 +115,8 @@ static SEL objSel;
|
|||
{
|
||||
NSUInteger count = map.nodeCount;
|
||||
SEL sel = @selector(encodeObject:);
|
||||
IMP imp = [aCoder methodForSelector: sel];
|
||||
id (*imp)(id,SEL,id)
|
||||
= (id (*)(id,SEL,id))[aCoder methodForSelector: sel];
|
||||
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
|
||||
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
|
||||
|
||||
|
@ -152,7 +153,8 @@ static SEL objSel;
|
|||
id key;
|
||||
id value;
|
||||
SEL sel = @selector(decodeValueOfObjCType:at:);
|
||||
IMP imp = [aCoder methodForSelector: sel];
|
||||
void (*imp)(id,SEL,const char*,void*)
|
||||
= (void (*)(id,SEL,const char*,void*))[aCoder methodForSelector: sel];
|
||||
const char *type = @encode(id);
|
||||
|
||||
[aCoder decodeValueOfObjCType: @encode(NSUInteger)
|
||||
|
@ -220,8 +222,9 @@ static SEL objSel;
|
|||
if (c > 0)
|
||||
{
|
||||
NSEnumerator *e = [other keyEnumerator];
|
||||
IMP nxtObj = [e methodForSelector: nxtSel];
|
||||
IMP otherObj = [other methodForSelector: objSel];
|
||||
id (*nxtObj)(id, SEL) = (id (*)(id,SEL))[e methodForSelector: nxtSel];
|
||||
id (*otherObj)(id, SEL, id)
|
||||
= (id (*)(id,SEL,id))[other methodForSelector: objSel];
|
||||
BOOL isProxy = [other isProxy];
|
||||
NSUInteger i;
|
||||
|
||||
|
@ -293,7 +296,8 @@ static SEL objSel;
|
|||
{
|
||||
GSIMapEnumerator_t enumerator;
|
||||
GSIMapNode node;
|
||||
IMP otherObj = [other methodForSelector: objSel];
|
||||
id (*otherObj)(id, SEL, id)
|
||||
= (id (*)(id,SEL,id))[other methodForSelector: objSel];
|
||||
|
||||
enumerator = GSIMapEnumeratorForMap(&map);
|
||||
while ((node = GSIMapEnumeratorNextNode(&enumerator)) != 0)
|
||||
|
|
|
@ -132,6 +132,7 @@ static NSString *CteContentType = @"content-type";
|
|||
static NSString *CteQuotedPrintable = @"quoted-printable";
|
||||
static NSString *CteXuuencode = @"x-uuencode";
|
||||
|
||||
typedef id (*oaiIMP)(id, SEL, NSUInteger);
|
||||
typedef BOOL (*boolIMP)(id, SEL, id);
|
||||
|
||||
static char *hex = "0123456789ABCDEF";
|
||||
|
@ -6184,12 +6185,12 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
|
|||
|
||||
if (count > 0)
|
||||
{
|
||||
IMP imp1;
|
||||
oaiIMP imp1;
|
||||
boolIMP imp2;
|
||||
|
||||
name = [name lowercaseString];
|
||||
|
||||
imp1 = [headers methodForSelector: @selector(objectAtIndex:)];
|
||||
imp1 = (oaiIMP)[headers methodForSelector: @selector(objectAtIndex:)];
|
||||
imp2 = (boolIMP)[name methodForSelector: @selector(isEqualToString:)];
|
||||
while (count-- > 0)
|
||||
{
|
||||
|
@ -6330,11 +6331,11 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
|
|||
if (count > 0)
|
||||
{
|
||||
NSUInteger index;
|
||||
IMP imp1;
|
||||
oaiIMP imp1;
|
||||
boolIMP imp2;
|
||||
|
||||
name = [headerClass makeToken: name preservingCase: NO];
|
||||
imp1 = [headers methodForSelector: @selector(objectAtIndex:)];
|
||||
imp1 = (oaiIMP)[headers methodForSelector: @selector(objectAtIndex:)];
|
||||
imp2 = (boolIMP)[name methodForSelector: @selector(isEqualToString:)];
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
|
@ -6364,10 +6365,10 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
|
|||
{
|
||||
NSUInteger index;
|
||||
NSMutableArray *array;
|
||||
IMP imp1;
|
||||
oaiIMP imp1;
|
||||
boolIMP imp2;
|
||||
|
||||
imp1 = [headers methodForSelector: @selector(objectAtIndex:)];
|
||||
imp1 = (oaiIMP)[headers methodForSelector: @selector(objectAtIndex:)];
|
||||
imp2 = (boolIMP)[name methodForSelector: @selector(isEqualToString:)];
|
||||
array = [NSMutableArray array];
|
||||
|
||||
|
@ -7285,10 +7286,10 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
|
|||
if (count > 0)
|
||||
{
|
||||
NSUInteger index;
|
||||
IMP imp1;
|
||||
oaiIMP imp1;
|
||||
boolIMP imp2;
|
||||
|
||||
imp1 = [headers methodForSelector: @selector(objectAtIndex:)];
|
||||
imp1 = (oaiIMP)[headers methodForSelector: @selector(objectAtIndex:)];
|
||||
imp2 = (boolIMP)[name methodForSelector: @selector(isEqualToString:)];
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
|
@ -7310,10 +7311,10 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
|
|||
|
||||
if (count > 0)
|
||||
{
|
||||
IMP imp1;
|
||||
oaiIMP imp1;
|
||||
boolIMP imp2;
|
||||
|
||||
imp1 = [headers methodForSelector: @selector(objectAtIndex:)];
|
||||
imp1 = (oaiIMP)[headers methodForSelector: @selector(objectAtIndex:)];
|
||||
imp2 = (boolIMP)[name methodForSelector: @selector(isEqualToString:)];
|
||||
while (count-- > 0)
|
||||
{
|
||||
|
|
|
@ -1983,7 +1983,7 @@ GSAutoreleasedBuffer(unsigned size)
|
|||
static Class buffer_class = 0;
|
||||
static Class autorelease_class;
|
||||
static SEL autorelease_sel;
|
||||
static IMP autorelease_imp;
|
||||
static id (*autorelease_imp)(Class, SEL, id);
|
||||
static int instance_size;
|
||||
static int offset;
|
||||
NSObject *o;
|
||||
|
@ -1995,7 +1995,8 @@ GSAutoreleasedBuffer(unsigned size)
|
|||
offset = instance_size % ALIGN;
|
||||
autorelease_class = [NSAutoreleasePool class];
|
||||
autorelease_sel = @selector(addObject:);
|
||||
autorelease_imp = [autorelease_class methodForSelector: autorelease_sel];
|
||||
autorelease_imp = (id (*)(Class, SEL, id))
|
||||
[autorelease_class methodForSelector: autorelease_sel];
|
||||
}
|
||||
o = (NSObject*)NSAllocateObject(buffer_class,
|
||||
size + offset, NSDefaultMallocZone());
|
||||
|
@ -2065,7 +2066,9 @@ GSPrintf (FILE *fptr, NSString* format, ...)
|
|||
# define AADD(c, o)
|
||||
# define AREM(c, o)
|
||||
# endif
|
||||
|
||||
#else
|
||||
# define AADD(c, o)
|
||||
# define AREM(c, o)
|
||||
#endif /* defined(GNUSTEP_BASE_LIBRARY) */
|
||||
|
||||
void
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
*/
|
||||
static Class NSString_class;
|
||||
static Class treeClass;
|
||||
static IMP usImp;
|
||||
static id (*usImp)(id, SEL, const unsigned char*);
|
||||
static SEL usSel;
|
||||
|
||||
static xmlExternalEntityLoader originalLoader = NULL;
|
||||
|
@ -166,7 +166,8 @@ setupCache()
|
|||
xmlDefaultSAXHandlerInit();
|
||||
NSString_class = [NSString class];
|
||||
usSel = @selector(stringWithUTF8String:);
|
||||
usImp = [NSString_class methodForSelector: usSel];
|
||||
usImp = (id (*)(id, SEL, const unsigned char*))
|
||||
[NSString_class methodForSelector: usSel];
|
||||
treeClass = [GSTreeSAXHandler class];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
NSUInteger lower = 0;
|
||||
NSUInteger index;
|
||||
SEL oaiSel;
|
||||
IMP oai;
|
||||
id (*oai)(id,SEL,NSUInteger);
|
||||
|
||||
if (item == nil)
|
||||
{
|
||||
|
@ -52,7 +52,7 @@
|
|||
}
|
||||
|
||||
oaiSel = @selector(objectAtIndex:);
|
||||
oai = [self methodForSelector: oaiSel];
|
||||
oai = (id(*)(id,SEL,NSUInteger))[self methodForSelector: oaiSel];
|
||||
/*
|
||||
* Binary search for an item equal to the one to be inserted.
|
||||
*/
|
||||
|
@ -95,7 +95,7 @@
|
|||
NSUInteger index;
|
||||
NSComparisonResult (*imp)(id, SEL, id);
|
||||
SEL oaiSel;
|
||||
IMP oai;
|
||||
id (*oai)(id,SEL,NSUInteger);
|
||||
|
||||
if (item == nil)
|
||||
{
|
||||
|
@ -115,7 +115,7 @@
|
|||
}
|
||||
|
||||
oaiSel = @selector(objectAtIndex:);
|
||||
oai = [self methodForSelector: oaiSel];
|
||||
oai = (id(*)(id,SEL,NSUInteger))[self methodForSelector: oaiSel];
|
||||
/*
|
||||
* Binary search for an item equal to the one to be inserted.
|
||||
*/
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#import "Foundation/NSException.h"
|
||||
#import "Foundation/NSHashTable.h"
|
||||
#import "Foundation/NSLock.h"
|
||||
#import "GNUstepBase/GSObjCRuntime.h"
|
||||
#import "GNUstepBase/NSObject+GNUstepBase.h"
|
||||
#import "GNUstepBase/NSDebug+GNUstepBase.h"
|
||||
#import "GNUstepBase/NSThread+GNUstepBase.h"
|
||||
|
@ -412,7 +413,9 @@ handleExit()
|
|||
NSUInteger size;
|
||||
|
||||
#if GS_SIZEOF_VOIDP > 4
|
||||
if ((((NSUInteger)void*)self) & 0x07)
|
||||
NSUInteger xxx = (NSUInteger)(void*)self;
|
||||
|
||||
if (xxx & 0x07)
|
||||
{
|
||||
return 0; // Small object has no size
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ static BOOL debugTemporarilyDisabled = NO;
|
|||
|
||||
BOOL GSDebugSet(NSString *level)
|
||||
{
|
||||
static IMP debugImp = 0;
|
||||
static id (*debugImp)(id,SEL,id) = 0;
|
||||
static SEL debugSel;
|
||||
|
||||
if (debugTemporarilyDisabled == YES)
|
||||
|
@ -53,7 +53,7 @@ BOOL GSDebugSet(NSString *level)
|
|||
{
|
||||
[[NSProcessInfo processInfo] debugSet];
|
||||
}
|
||||
debugImp = [_debug_set methodForSelector: debugSel];
|
||||
debugImp = (id (*)(id,SEL,id))[_debug_set methodForSelector: debugSel];
|
||||
if (debugImp == 0)
|
||||
{
|
||||
fprintf(stderr, "Unable to set up with [NSProcessInfo-debugSet]\n");
|
||||
|
|
|
@ -415,7 +415,8 @@ OAppend(id obj, NSDictionary *loc, unsigned lev, unsigned step,
|
|||
const char *iBaseString;
|
||||
const char *iSizeString;
|
||||
SEL objSel = @selector(objectForKey:);
|
||||
IMP myObj = [obj methodForSelector: objSel];
|
||||
id (*myObj)(id,SEL,id)
|
||||
= (id(*)(id,SEL,id))[obj methodForSelector: objSel];
|
||||
unsigned i;
|
||||
NSArray *keyArray = [obj allKeys];
|
||||
unsigned numKeys = [keyArray count];
|
||||
|
@ -642,7 +643,8 @@ OAppend(id obj, NSDictionary *loc, unsigned lev, unsigned step,
|
|||
OAppend(aPropertyList, loc, 0, step > 3 ? 3 : step, dest);
|
||||
return dest;
|
||||
}
|
||||
return (*originalImp)(self, _cmd, aPropertyList, aFormat, anErrorString);
|
||||
return (*(id(*)(id,SEL,id,id,id))originalImp)
|
||||
(self, _cmd, aPropertyList, aFormat, anErrorString);
|
||||
}
|
||||
|
||||
+ (void) load
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
|
@ -49,12 +49,6 @@
|
|||
#undef GNUSTEP_INDEX_CHARSET
|
||||
|
||||
#import "NSCharacterSetData.h"
|
||||
#import "CharSets/URLFragmentAllowedCharSet.h"
|
||||
#import "CharSets/URLHostAllowedCharSet.h"
|
||||
#import "CharSets/URLPasswordAllowedCharSet.h"
|
||||
#import "CharSets/URLPathAllowedCharSet.h"
|
||||
#import "CharSets/URLQueryAllowedCharSet.h"
|
||||
#import "CharSets/URLUserAllowedCharSet.h"
|
||||
|
||||
#define GSUNICODE_MAX 1114112
|
||||
#define GSBITMAP_SIZE 8192
|
||||
|
@ -122,6 +116,20 @@
|
|||
i--;
|
||||
}
|
||||
i *= GSBITMAP_SIZE;
|
||||
if (GSBITMAP_SIZE == i)
|
||||
{
|
||||
/* In the base plane, find the number of used bytes, so we don't
|
||||
* produce a bitmap that is longer than necessary.
|
||||
*/
|
||||
if (_length < i)
|
||||
{
|
||||
i = _length;
|
||||
}
|
||||
while (i > 0 && 0 == _data[i - 1])
|
||||
{
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if (i < _length)
|
||||
{
|
||||
return [NSData dataWithBytes: _data length: i];
|
||||
|
@ -206,7 +214,7 @@
|
|||
{
|
||||
unsigned length = [bitmap length];
|
||||
|
||||
if ((length % GSBITMAP_SIZE) != 0 || length > GSBITMAP_MAX)
|
||||
if (length > GSBITMAP_MAX)
|
||||
{
|
||||
NSLog(@"attempt to initialize character set with invalid bitmap");
|
||||
[self dealloc];
|
||||
|
@ -280,13 +288,22 @@
|
|||
}
|
||||
|
||||
/* Make space if needed.
|
||||
* Use exact size if we have nothing beyond the base plane,
|
||||
* otherwise round up to a plane boundary.
|
||||
*/
|
||||
b = (m - 1) / 8;
|
||||
if (b >= _length)
|
||||
{
|
||||
while (b >= _length)
|
||||
if (b < GSBITMAP_SIZE)
|
||||
{
|
||||
_length += GSBITMAP_SIZE;
|
||||
_length = b + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (b >= _length)
|
||||
{
|
||||
_length += GSBITMAP_SIZE;
|
||||
}
|
||||
}
|
||||
[_obj setLength: _length];
|
||||
_data = [_obj mutableBytes];
|
||||
|
@ -337,10 +354,14 @@
|
|||
if (length > 0)
|
||||
{
|
||||
NSUInteger i;
|
||||
unsigned max = _length;
|
||||
unichar (*get)(id, SEL, NSUInteger);
|
||||
|
||||
get = (unichar (*)(id, SEL, NSUInteger))
|
||||
[aString methodForSelector: @selector(characterAtIndex:)];
|
||||
|
||||
/* Determine size of bitmap needed.
|
||||
*/
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
unichar letter;
|
||||
|
@ -358,15 +379,49 @@
|
|||
+ (second - 0xdc00) + 0x0010000;
|
||||
}
|
||||
byte = letter/8;
|
||||
if (byte >= _length)
|
||||
if (byte >= max)
|
||||
{
|
||||
while (byte >= _length)
|
||||
max = byte;
|
||||
}
|
||||
}
|
||||
/* Make space if needed.
|
||||
* Use exact size if we have nothing beyond the base plane,
|
||||
* otherwise round up to a plane boundary.
|
||||
*/
|
||||
if (max >= _length)
|
||||
{
|
||||
if (max < GSBITMAP_SIZE)
|
||||
{
|
||||
_length = max + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (max >= _length)
|
||||
{
|
||||
_length += GSBITMAP_SIZE;
|
||||
}
|
||||
[_obj setLength: _length];
|
||||
_data = [_obj mutableBytes];
|
||||
}
|
||||
[_obj setLength: _length];
|
||||
_data = [_obj mutableBytes];
|
||||
}
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
unichar letter;
|
||||
unichar second;
|
||||
unsigned byte;
|
||||
|
||||
letter = (*get)(aString, @selector(characterAtIndex:), i);
|
||||
// Convert a surrogate pair if necessary
|
||||
if (letter >= 0xd800 && letter <= 0xdbff && i < length-1
|
||||
&& (second = (*get)(aString, @selector(characterAtIndex:), i+1))
|
||||
>= 0xdc00 && second <= 0xdfff)
|
||||
{
|
||||
i++;
|
||||
letter = ((letter - 0xd800) << 10)
|
||||
+ (second - 0xdc00) + 0x0010000;
|
||||
}
|
||||
byte = letter/8;
|
||||
GSSETBIT(_data[byte], letter % 8);
|
||||
}
|
||||
}
|
||||
|
@ -382,6 +437,20 @@
|
|||
i--;
|
||||
}
|
||||
i *= GSBITMAP_SIZE;
|
||||
if (GSBITMAP_SIZE == i)
|
||||
{
|
||||
/* In the base plane, find the number of used bytes, so we don't
|
||||
* produce a bitmap that is longer than necessary.
|
||||
*/
|
||||
if (_length < i)
|
||||
{
|
||||
i = _length;
|
||||
}
|
||||
while (i > 0 && 0 == _data[i - 1])
|
||||
{
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return [NSData dataWithBytes: _data length: i];
|
||||
}
|
||||
|
||||
|
@ -430,7 +499,7 @@
|
|||
unsigned length = [bitmap length];
|
||||
id tmp;
|
||||
|
||||
if ((length % GSBITMAP_SIZE) != 0 || length > GSBITMAP_MAX)
|
||||
if (length > GSBITMAP_MAX)
|
||||
{
|
||||
NSLog(@"attempt to initialize character set with invalid bitmap");
|
||||
[self dealloc];
|
||||
|
@ -623,7 +692,8 @@ static Class concreteMutableClass = nil;
|
|||
|
||||
- (id) initWithBitmap: (NSData*)bitmap number: (int)number
|
||||
{
|
||||
if ((self = (_GSStaticCharSet*)[(NSBitmapCharSet*)self initWithBitmap: bitmap]) != nil)
|
||||
if ((self = (_GSStaticCharSet*)[(NSBitmapCharSet*)self
|
||||
initWithBitmap: bitmap]) != nil)
|
||||
{
|
||||
_index = number;
|
||||
}
|
||||
|
@ -841,56 +911,66 @@ static Class concreteMutableClass = nil;
|
|||
|
||||
+ (id) URLFragmentAllowedCharacterSet
|
||||
{
|
||||
return [self _staticSet: urlFragmentAllowedCharSet
|
||||
length: sizeof(urlFragmentAllowedCharSet)
|
||||
return [self _staticSet: URLFragmentAllowedCharSet
|
||||
length: sizeof(URLFragmentAllowedCharSet)
|
||||
number: 15];
|
||||
}
|
||||
|
||||
+ (id) URLPasswordAllowedCharacterSet
|
||||
{
|
||||
return [self _staticSet: urlPasswordAllowedCharSet
|
||||
length: sizeof(urlPasswordAllowedCharSet)
|
||||
return [self _staticSet: URLPasswordAllowedCharSet
|
||||
length: sizeof(URLPasswordAllowedCharSet)
|
||||
number: 16];
|
||||
}
|
||||
|
||||
+ (id) URLPathAllowedCharacterSet
|
||||
{
|
||||
return [self _staticSet: urlPathAllowedCharSet
|
||||
length: sizeof(urlPathAllowedCharSet)
|
||||
return [self _staticSet: URLPathAllowedCharSet
|
||||
length: sizeof(URLPathAllowedCharSet)
|
||||
number: 17];
|
||||
}
|
||||
|
||||
+ (id) URLQueryAllowedCharacterSet
|
||||
{
|
||||
return [self _staticSet: urlQueryAllowedCharSet
|
||||
length: sizeof(urlQueryAllowedCharSet)
|
||||
return [self _staticSet: URLQueryAllowedCharSet
|
||||
length: sizeof(URLQueryAllowedCharSet)
|
||||
number: 18];
|
||||
}
|
||||
|
||||
+ (id) URLUserAllowedCharacterSet
|
||||
{
|
||||
return [self _staticSet: urlUserAllowedCharSet
|
||||
length: sizeof(urlUserAllowedCharSet)
|
||||
return [self _staticSet: URLUserAllowedCharSet
|
||||
length: sizeof(URLUserAllowedCharSet)
|
||||
number: 19];
|
||||
}
|
||||
|
||||
+ (id) URLHostAllowedCharacterSet
|
||||
{
|
||||
return [self _staticSet: urlHostAllowedCharSet
|
||||
length: sizeof(urlHostAllowedCharSet)
|
||||
return [self _staticSet: URLHostAllowedCharSet
|
||||
length: sizeof(URLHostAllowedCharSet)
|
||||
number: 20];
|
||||
}
|
||||
|
||||
- (NSData*) bitmapRepresentation
|
||||
{
|
||||
BOOL (*imp)(id, SEL, unichar);
|
||||
NSMutableData *m = [NSMutableData dataWithLength: 8192];
|
||||
unsigned char *p = (unsigned char*)[m mutableBytes];
|
||||
NSMutableData *m;
|
||||
unsigned char *p;
|
||||
unsigned end;
|
||||
unsigned i;
|
||||
|
||||
imp = (BOOL (*)(id,SEL,unichar))
|
||||
[self methodForSelector: @selector(characterIsMember:)];
|
||||
for (i = 0; i <= 0xffff; i++)
|
||||
for (end = 0xffff; end > 0; end--)
|
||||
{
|
||||
if (imp(self, @selector(characterIsMember:), end) == YES)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
m = [NSMutableData dataWithLength: end / 8 + 1];
|
||||
p = (unsigned char*)[m mutableBytes];
|
||||
for (i = 0; i <= end; i++)
|
||||
{
|
||||
if (imp(self, @selector(characterIsMember:), i) == YES)
|
||||
{
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -34,7 +34,7 @@
|
|||
also contain commas, most notably in the Expires field (which is not quoted
|
||||
and can contain spaces as well). The last key/value does not have to have a
|
||||
semi-colon, so this can be tricky to parse if another cookie occurs
|
||||
after this (See GSRangeOfCookie).
|
||||
after this (See GSCookieStrings).
|
||||
*/
|
||||
|
||||
#import "common.h"
|
||||
|
@ -114,7 +114,7 @@ static const unsigned char whitespace[32] = {
|
|||
#define GS_IS_WHITESPACE(X) IS_BIT_SET(whitespace[(X)/8], (X) % 8)
|
||||
|
||||
static id GSPropertyListFromCookieFormat(NSString *string, int version);
|
||||
static NSRange GSRangeOfCookie(NSString *string);
|
||||
static NSMutableArray *GSCookieStrings(NSString *string);
|
||||
|
||||
@implementation NSHTTPCookie
|
||||
|
||||
|
@ -141,36 +141,42 @@ static NSRange GSRangeOfCookie(NSString *string);
|
|||
forHeader: (NSString *)header
|
||||
andURL: (NSURL *)url
|
||||
{
|
||||
int version;
|
||||
NSString *defaultPath, *defaultDomain;
|
||||
NSMutableArray *a;
|
||||
int version;
|
||||
NSString *defaultPath;
|
||||
NSString *defaultDomain;
|
||||
NSMutableArray *cookies;
|
||||
NSUInteger count;
|
||||
|
||||
if ([header isEqual: @"Set-Cookie"])
|
||||
version = 0;
|
||||
{
|
||||
version = 0;
|
||||
}
|
||||
else if ([header isEqual: @"Set-Cookie2"])
|
||||
version = 1;
|
||||
{
|
||||
version = 1;
|
||||
}
|
||||
else
|
||||
return nil;
|
||||
|
||||
a = [NSMutableArray array];
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
defaultDomain = [url host];
|
||||
defaultPath = [url path];
|
||||
if ([[url absoluteString] hasSuffix: @"/"] == NO)
|
||||
defaultPath = [defaultPath stringByDeletingLastPathComponent];
|
||||
{
|
||||
defaultPath = [defaultPath stringByDeletingLastPathComponent];
|
||||
}
|
||||
|
||||
cookies = GSCookieStrings(field);
|
||||
count = [cookies count];
|
||||
/* We could use an NSScanner here, but this string could contain all
|
||||
sorts of odd stuff. It's not quite a property list either - it has
|
||||
dates and also could have tokens without values. */
|
||||
while (1)
|
||||
while (count-- > 0)
|
||||
{
|
||||
NSHTTPCookie *cookie;
|
||||
NSMutableDictionary *dict;
|
||||
NSString *onecookie;
|
||||
NSRange range = GSRangeOfCookie(field);
|
||||
NSHTTPCookie *cookie;
|
||||
NSMutableDictionary *dict;
|
||||
NSString *onecookie = [cookies objectAtIndex: count];
|
||||
|
||||
if (range.location == NSNotFound)
|
||||
break;
|
||||
onecookie = [field substringWithRange: range];
|
||||
NS_DURING
|
||||
dict = GSPropertyListFromCookieFormat(onecookie, version);
|
||||
NS_HANDLER
|
||||
|
@ -179,18 +185,25 @@ static NSRange GSRangeOfCookie(NSString *string);
|
|||
if ([dict count])
|
||||
{
|
||||
if ([dict objectForKey: NSHTTPCookiePath] == nil)
|
||||
[dict setObject: defaultPath forKey: NSHTTPCookiePath];
|
||||
{
|
||||
[dict setObject: defaultPath forKey: NSHTTPCookiePath];
|
||||
}
|
||||
if ([dict objectForKey: NSHTTPCookieDomain] == nil)
|
||||
[dict setObject: defaultDomain forKey: NSHTTPCookieDomain];
|
||||
{
|
||||
[dict setObject: defaultDomain forKey: NSHTTPCookieDomain];
|
||||
}
|
||||
cookie = [NSHTTPCookie cookieWithProperties: dict];
|
||||
if (cookie)
|
||||
[a addObject: cookie];
|
||||
{
|
||||
[cookies replaceObjectAtIndex: count withObject: cookie];
|
||||
}
|
||||
else
|
||||
{
|
||||
[cookies removeObjectAtIndex: count];
|
||||
}
|
||||
}
|
||||
if ([field length] <= NSMaxRange(range))
|
||||
break;
|
||||
field = [field substringFromIndex: NSMaxRange(range)+1];
|
||||
}
|
||||
return a;
|
||||
return cookies;
|
||||
}
|
||||
|
||||
+ (NSArray *) cookiesWithResponseHeaderFields: (NSDictionary *)headerFields
|
||||
|
@ -833,72 +846,139 @@ GSPropertyListFromCookieFormat(NSString *string, int version)
|
|||
return AUTORELEASE(dict);
|
||||
}
|
||||
|
||||
/* Look for the comma that separates cookies. Commas can also occur in
|
||||
date strings, like "expires", but perhaps it can occur other places.
|
||||
For instance, the key/value pair key=value1,value2 is not really
|
||||
valid, but should we handle it anyway? Definitely we should handle the
|
||||
perfectly normal case of:
|
||||
|
||||
Set-Cookie: domain=test.com; expires=Thu, 12-Sep-2109 14:58:04 GMT;
|
||||
session=foo
|
||||
Set-Cookie: bar=baz
|
||||
|
||||
which gets concatenated into something like:
|
||||
|
||||
Set-Cookie: domain=test.com; expires=Thu, 12-Sep-2109 14:58:04 GMT;
|
||||
session=foo,bar=baz
|
||||
|
||||
*/
|
||||
static NSRange
|
||||
GSRangeOfCookie(NSString *string)
|
||||
/* Split a string containing comma seprated cookeie settings into an array
|
||||
* of individual cookie specifications.
|
||||
* Look for the comma that separates cookies. Commas can also occur in
|
||||
* date strings, like "expires", but perhaps it can occur other places.
|
||||
* For instance, the key/value pair key=value1,value2 is not really
|
||||
* valid, but should we handle it anyway? Definitely we should handle the
|
||||
* perfectly normal case of:
|
||||
*
|
||||
* Set-Cookie: domain=test.com; expires=Thu, 12-Sep-2109 14:58:04 GMT;
|
||||
* session=foo
|
||||
* Set-Cookie: bar=baz
|
||||
*
|
||||
* which gets concatenated into something like:
|
||||
*
|
||||
* Set-Cookie: domain=test.com; expires=Thu, 12-Sep-2109 14:58:04 GMT;
|
||||
* session=foo,bar=baz
|
||||
*/
|
||||
static NSMutableArray*
|
||||
GSCookieStrings(NSString *string)
|
||||
{
|
||||
pldata _pld;
|
||||
pldata *pld = &_pld;
|
||||
unsigned char *ptr;
|
||||
unsigned pos;
|
||||
unsigned end;
|
||||
NSData *d;
|
||||
NSRange range;
|
||||
NSMutableArray *cookies;
|
||||
unsigned start = 0;
|
||||
unsigned saved = 0;
|
||||
|
||||
/*
|
||||
* An empty string is a nil property list.
|
||||
*/
|
||||
range = NSMakeRange(NSNotFound, NSNotFound);
|
||||
if ([string length] == 0)
|
||||
{
|
||||
return range;
|
||||
return nil;
|
||||
}
|
||||
|
||||
d = [string dataUsingEncoding: NSUTF8StringEncoding];
|
||||
NSCAssert(d, @"Couldn't get utf8 data from string.");
|
||||
_pld.ptr = (unsigned char*)[d bytes];
|
||||
_pld.pos = 0;
|
||||
_pld.end = [d length];
|
||||
_pld.err = nil;
|
||||
_pld.lin = 0;
|
||||
_pld.opt = 0;
|
||||
_pld.key = NO;
|
||||
_pld.old = YES; // OpenStep style
|
||||
ptr = (unsigned char*)[d bytes];
|
||||
pos = 0;
|
||||
end = [d length];
|
||||
|
||||
while (skipSpace(pld) == YES)
|
||||
cookies = [NSMutableArray arrayWithCapacity: 4];
|
||||
while (pos < end)
|
||||
{
|
||||
if (pld->ptr[pld->pos] == ',')
|
||||
while (pos < end && isspace(ptr[pos]))
|
||||
{
|
||||
/* Look ahead for something that will tell us if this is a
|
||||
separate cookie or not */
|
||||
unsigned saved_pos = pld->pos;
|
||||
while (pld->ptr[pld->pos] != '=' && pld->ptr[pld->pos] != ';'
|
||||
&& pld->ptr[pld->pos] != ',' && pld->pos < pld->end )
|
||||
pld->pos++;
|
||||
if (pld->ptr[pld->pos] == '=')
|
||||
{
|
||||
/* Separate comment */
|
||||
range = NSMakeRange(0, saved_pos-1);
|
||||
break;
|
||||
}
|
||||
pld->pos = saved_pos;
|
||||
pos++;
|
||||
}
|
||||
pld->pos++;
|
||||
}
|
||||
if (range.location == NSNotFound)
|
||||
range = NSMakeRange(0, [string length]);
|
||||
start = pos;
|
||||
|
||||
return range;
|
||||
while (pos < end)
|
||||
{
|
||||
if (ptr[pos] == ',')
|
||||
{
|
||||
/* Look ahead for something that will tell us if this is a
|
||||
* separate cookie or not. We look for something of the form
|
||||
* ' token =' where a space represents any optional whitespace.
|
||||
*/
|
||||
saved = pos++;
|
||||
while (pos < end && isspace(ptr[pos]))
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
if (pos < end)
|
||||
{
|
||||
const char *bad = "()<>@,;:\\\"/[]?={}";
|
||||
int c = ptr[pos];
|
||||
|
||||
/* skip past token characters.
|
||||
*/
|
||||
while (c > 32 && c < 128 && strchr(bad, c) == 0)
|
||||
{
|
||||
pos++;
|
||||
if (pos < end)
|
||||
{
|
||||
c = ptr[pos];
|
||||
}
|
||||
}
|
||||
while (pos < end && isspace(ptr[pos]))
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
if (pos < end && '=' == ptr[pos])
|
||||
{
|
||||
pos = saved + 1;
|
||||
/* We found a comma separator: so make the text before
|
||||
* the comma a cooke string as long as it is not empty.
|
||||
*/
|
||||
while (saved > start
|
||||
&& isspace(ptr[saved - 1]))
|
||||
{
|
||||
saved--;
|
||||
}
|
||||
if (saved > start)
|
||||
{
|
||||
NSString *str = [NSString alloc];
|
||||
|
||||
str = [str initWithBytes: ptr + start
|
||||
length: saved - start
|
||||
encoding: NSUTF8StringEncoding];
|
||||
[cookies addObject: str];
|
||||
RELEASE(str);
|
||||
}
|
||||
start = saved = pos;
|
||||
}
|
||||
}
|
||||
pos = saved;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
if (pos > start)
|
||||
{
|
||||
/* There was data after the last comma; make it into a cookie string
|
||||
* as long as it's not empty after removing spaces
|
||||
*/
|
||||
saved = pos;
|
||||
while (saved > start
|
||||
&& isspace(ptr[saved - 1]))
|
||||
{
|
||||
saved--;
|
||||
}
|
||||
if (saved > start)
|
||||
{
|
||||
NSString *str = [NSString alloc];
|
||||
|
||||
/* There may not be room to add a nul terminator, so we use an
|
||||
* initialiser which doesn't need one.
|
||||
*/
|
||||
str = [str initWithBytes: ptr + start
|
||||
length: saved - start
|
||||
encoding: NSUTF8StringEncoding];
|
||||
[cookies addObject: str];
|
||||
RELEASE(str);
|
||||
}
|
||||
}
|
||||
return cookies; // The individual cookies
|
||||
}
|
||||
|
|
|
@ -627,6 +627,11 @@ static NSRecursiveLock *classLock = nil;
|
|||
[[dict objectForKey: NSLocaleCollationIdentifier] UTF8String];
|
||||
const char *currency = [[dict objectForKey: NSLocaleCurrencyCode] UTF8String];
|
||||
|
||||
if (!calendar)
|
||||
{
|
||||
calendar = [[dict objectForKey: NSLocaleCalendarIdentifier] UTF8String];
|
||||
}
|
||||
|
||||
// A locale cannot be constructed without a language.
|
||||
if (language == NULL)
|
||||
return nil;
|
||||
|
|
|
@ -110,6 +110,11 @@ static Class concreteClass = 0;
|
|||
[self name], [self object], [self userInfo]];
|
||||
}
|
||||
|
||||
- (NSUInteger) hash
|
||||
{
|
||||
return [[self name] hash] ^ [[self object] hash];
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ([self class] == abstractClass)
|
||||
|
@ -122,6 +127,22 @@ static Class concreteClass = 0;
|
|||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) isEqual: (id)other
|
||||
{
|
||||
NSNotification *o;
|
||||
NSObject *v1;
|
||||
NSObject *v2;
|
||||
|
||||
if (NO == [(o = other) isKindOfClass: [NSNotification class]]
|
||||
|| ((v1 = [self name]) != (v2 = [o name]) && ![v1 isEqual: v2])
|
||||
|| ((v1 = [self object]) != (v2 = [o object]) && ![v1 isEqual: v2])
|
||||
|| ((v1 = [self userInfo]) != (v2 = [o userInfo]) && ![v1 isEqual: v2]))
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the notification name.
|
||||
*/
|
||||
|
|
|
@ -217,6 +217,7 @@ static NSArray *empty = nil;
|
|||
RELEASE(internal->dependencies);
|
||||
RELEASE(internal->cond);
|
||||
RELEASE(internal->lock);
|
||||
RELEASE(internal->completionBlock);
|
||||
GS_DESTROY_INTERNAL(NSOperation);
|
||||
}
|
||||
[super dealloc];
|
||||
|
@ -381,7 +382,7 @@ static NSArray *empty = nil;
|
|||
|
||||
- (void) setCompletionBlock: (GSOperationCompletionBlock)aBlock
|
||||
{
|
||||
internal->completionBlock = aBlock;
|
||||
ASSIGNCOPY(internal->completionBlock, aBlock);
|
||||
}
|
||||
|
||||
- (void) setQueuePriority: (NSOperationQueuePriority)pri
|
||||
|
@ -1099,9 +1100,18 @@ static NSOperationQueue *mainQueue = nil;
|
|||
|| (pending > 0 && internal->threadCount < POOL))
|
||||
{
|
||||
internal->threadCount++;
|
||||
[NSThread detachNewThreadSelector: @selector(_thread)
|
||||
toTarget: self
|
||||
withObject: nil];
|
||||
NS_DURING
|
||||
{
|
||||
[NSThread detachNewThreadSelector: @selector(_thread)
|
||||
toTarget: self
|
||||
withObject: nil];
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
NSLog(@"Failed to create thread for %@: %@",
|
||||
self, localException);
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
}
|
||||
/* Tell the thread pool that there is an operation to start.
|
||||
*/
|
||||
|
|
|
@ -1901,7 +1901,8 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
|
|||
}
|
||||
}
|
||||
|
||||
- (NSString *) stringByAddingPercentEncodingWithAllowedCharacters: (NSCharacterSet *)aSet
|
||||
- (NSString *) stringByAddingPercentEncodingWithAllowedCharacters:
|
||||
(NSCharacterSet *)aSet
|
||||
{
|
||||
NSData *data = [self dataUsingEncoding: NSUTF8StringEncoding];
|
||||
NSString *s = nil;
|
||||
|
@ -1921,7 +1922,10 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
|
|||
unsigned int hi;
|
||||
unsigned int lo;
|
||||
|
||||
if([aSet characterIsMember: c]) // if the character is in the allowed set, put it in
|
||||
/* If the character is in the allowed set *and* is in the
|
||||
* 7-bit ASCII range, it can be added unchanged.
|
||||
*/
|
||||
if (c < 128 && [aSet characterIsMember: c])
|
||||
{
|
||||
dst[dpos++] = c;
|
||||
}
|
||||
|
@ -1936,7 +1940,7 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
|
|||
}
|
||||
s = [[NSString alloc] initWithBytes: dst
|
||||
length: dpos
|
||||
encoding: NSUTF8StringEncoding];
|
||||
encoding: NSASCIIStringEncoding];
|
||||
NSZoneFree(NSDefaultMallocZone(), dst);
|
||||
IF_NO_GC([s autorelease];)
|
||||
}
|
||||
|
@ -1963,7 +1967,7 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
|
|||
uint8_t hi = s[index+1];
|
||||
uint8_t lo = s[index+2];
|
||||
|
||||
if (isdigit(hi) && isxdigit(lo))
|
||||
if (isxdigit(hi) && isxdigit(lo))
|
||||
{
|
||||
index += 2;
|
||||
if (hi <= '9')
|
||||
|
|
191
Source/NSURL.m
191
Source/NSURL.m
|
@ -68,6 +68,7 @@ function may be incorrect
|
|||
#import "common.h"
|
||||
#define EXPOSE_NSURL_IVARS 1
|
||||
#import "Foundation/NSArray.h"
|
||||
#import "Foundation/NSAutoreleasePool.h"
|
||||
#import "Foundation/NSCoder.h"
|
||||
#import "Foundation/NSData.h"
|
||||
#import "Foundation/NSDictionary.h"
|
||||
|
@ -89,138 +90,6 @@ function may be incorrect
|
|||
NSString * const NSURLErrorDomain = @"NSURLErrorDomain";
|
||||
NSString * const NSErrorFailingURLStringKey = @"NSErrorFailingURLStringKey";
|
||||
|
||||
@interface NSString (NSURLPrivate)
|
||||
- (NSString*) _stringByAddingPercentEscapes;
|
||||
- (NSString*) _stringByAddingPercentEscapesForQuery;
|
||||
@end
|
||||
|
||||
@implementation NSString (NSURLPrivate)
|
||||
|
||||
/* Like the normal percent escape method, but with additional characters
|
||||
* escaped (for use by file scheme URLs).
|
||||
*/
|
||||
- (NSString*) _stringByAddingPercentEscapes
|
||||
{
|
||||
NSData *data = [self dataUsingEncoding: NSUTF8StringEncoding];
|
||||
NSString *s = nil;
|
||||
|
||||
if (data != nil)
|
||||
{
|
||||
unsigned char *src = (unsigned char*)[data bytes];
|
||||
unsigned int slen = [data length];
|
||||
unsigned char *dst;
|
||||
unsigned int spos = 0;
|
||||
unsigned int dpos = 0;
|
||||
|
||||
dst = (unsigned char*)NSZoneMalloc(NSDefaultMallocZone(), slen * 3);
|
||||
while (spos < slen)
|
||||
{
|
||||
unsigned char c = src[spos++];
|
||||
unsigned int hi;
|
||||
unsigned int lo;
|
||||
|
||||
if (c <= 32
|
||||
|| c > 126
|
||||
|| c == 34
|
||||
|| c == 35
|
||||
|| c == 37
|
||||
|| c == 59
|
||||
|| c == 60
|
||||
|| c == 62
|
||||
|| c == 63
|
||||
|| c == 91
|
||||
|| c == 92
|
||||
|| c == 93
|
||||
|| c == 94
|
||||
|| c == 96
|
||||
|| c == 123
|
||||
|| c == 124
|
||||
|| c == 125)
|
||||
{
|
||||
dst[dpos++] = '%';
|
||||
hi = (c & 0xf0) >> 4;
|
||||
dst[dpos++] = (hi > 9) ? 'A' + hi - 10 : '0' + hi;
|
||||
lo = (c & 0x0f);
|
||||
dst[dpos++] = (lo > 9) ? 'A' + lo - 10 : '0' + lo;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dpos++] = c;
|
||||
}
|
||||
}
|
||||
s = [[NSString alloc] initWithBytes: dst
|
||||
length: dpos
|
||||
encoding: NSASCIIStringEncoding];
|
||||
NSZoneFree(NSDefaultMallocZone(), dst);
|
||||
IF_NO_GC([s autorelease];)
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode query
|
||||
*/
|
||||
- (NSString*) _stringByAddingPercentEscapesForQuery
|
||||
{
|
||||
NSData *data = [self dataUsingEncoding: NSUTF8StringEncoding];
|
||||
NSString *s = nil;
|
||||
|
||||
if (data != nil)
|
||||
{
|
||||
unsigned char *src = (unsigned char*)[data bytes];
|
||||
unsigned int slen = [data length];
|
||||
unsigned char *dst;
|
||||
unsigned int spos = 0;
|
||||
unsigned int dpos = 0;
|
||||
|
||||
dst = (unsigned char*)NSZoneMalloc(NSDefaultMallocZone(), slen * 3);
|
||||
while (spos < slen)
|
||||
{
|
||||
unsigned char c = src[spos++];
|
||||
unsigned int hi;
|
||||
unsigned int lo;
|
||||
|
||||
if (c <= 32
|
||||
|| c > 126
|
||||
|| c == 34
|
||||
|| c == 35
|
||||
|| c == 37
|
||||
|| c == 38
|
||||
|| c == 59
|
||||
|| c == 60
|
||||
|| c == 61
|
||||
|| c == 62
|
||||
|| c == 91
|
||||
|| c == 92
|
||||
|| c == 93
|
||||
|| c == 94
|
||||
|| c == 96
|
||||
|| c == 123
|
||||
|| c == 124
|
||||
|| c == 125)
|
||||
{
|
||||
dst[dpos++] = '%';
|
||||
hi = (c & 0xf0) >> 4;
|
||||
dst[dpos++] = (hi > 9) ? 'A' + hi - 10 : '0' + hi;
|
||||
lo = (c & 0x0f);
|
||||
dst[dpos++] = (lo > 9) ? 'A' + lo - 10 : '0' + lo;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dpos++] = c;
|
||||
}
|
||||
}
|
||||
s = [[NSString alloc] initWithBytes: dst
|
||||
length: dpos
|
||||
encoding: NSASCIIStringEncoding];
|
||||
NSZoneFree(NSDefaultMallocZone(), dst);
|
||||
IF_NO_GC([s autorelease];)
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface NSURL (GSPrivate)
|
||||
- (NSURL*) _URLBySettingPath: (NSString*)newPath;
|
||||
@end
|
||||
|
@ -707,6 +576,7 @@ static char *unescape(const char *from, char * to)
|
|||
|
||||
@implementation NSURL
|
||||
|
||||
static NSCharacterSet *fileCharSet = nil;
|
||||
static NSUInteger urlAlign;
|
||||
|
||||
+ (id) fileURLWithPath: (NSString*)aPath
|
||||
|
@ -732,6 +602,8 @@ static NSUInteger urlAlign;
|
|||
NSGetSizeAndAlignment(@encode(parsedURL), &urlAlign, 0);
|
||||
clientsLock = [NSLock new];
|
||||
[[NSObject leakAt: &clientsLock] release];
|
||||
ASSIGN(fileCharSet, [NSCharacterSet characterSetWithCharactersInString:
|
||||
@"!$&'()*+,-./0123456789:=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -832,7 +704,8 @@ static NSUInteger urlAlign;
|
|||
|
||||
if ([aScheme isEqualToString: @"file"])
|
||||
{
|
||||
aPath = [aPath _stringByAddingPercentEscapes];
|
||||
aPath = [aPath stringByAddingPercentEncodingWithAllowedCharacters:
|
||||
fileCharSet];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2325,6 +2198,30 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
|
|||
|
||||
@implementation NSURLComponents
|
||||
|
||||
static NSCharacterSet *queryItemCharSet = nil;
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (nil == queryItemCharSet)
|
||||
{
|
||||
ENTER_POOL
|
||||
NSMutableCharacterSet *m;
|
||||
|
||||
m = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
|
||||
|
||||
/* Rationale: if a query item contained an ampersand we would not be
|
||||
* able to tell where one name/value pair ends and the next starts,
|
||||
* so we cannot permit that character in an item. Similarly, if a
|
||||
* query item contained an equals sign we would not be able to tell
|
||||
* where the name ends and the value starts, so we cannot permit that
|
||||
* character either.
|
||||
*/
|
||||
[m removeCharactersInString: @"&="];
|
||||
queryItemCharSet = [m copy];
|
||||
LEAVE_POOL
|
||||
}
|
||||
}
|
||||
|
||||
// Creating URL components...
|
||||
+ (instancetype) componentsWithString: (NSString *)urlString
|
||||
{
|
||||
|
@ -2765,8 +2662,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
|
|||
// Accessing Components in PercentEncoded Format
|
||||
- (NSString *) percentEncodedFragment
|
||||
{
|
||||
return [internal->_fragment stringByAddingPercentEncodingWithAllowedCharacters:
|
||||
[NSCharacterSet URLFragmentAllowedCharacterSet]];
|
||||
return [internal->_fragment
|
||||
stringByAddingPercentEncodingWithAllowedCharacters:
|
||||
[NSCharacterSet URLFragmentAllowedCharacterSet]];
|
||||
}
|
||||
|
||||
- (void) setPercentEncodedFragment: (NSString *)fragment
|
||||
|
@ -2776,8 +2674,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
|
|||
|
||||
- (NSString *) percentEncodedHost
|
||||
{
|
||||
return [internal->_host stringByAddingPercentEncodingWithAllowedCharacters:
|
||||
[NSCharacterSet URLHostAllowedCharacterSet]];
|
||||
return [internal->_host
|
||||
stringByAddingPercentEncodingWithAllowedCharacters:
|
||||
[NSCharacterSet URLHostAllowedCharacterSet]];
|
||||
}
|
||||
|
||||
- (void) setPercentEncodedHost: (NSString *)host
|
||||
|
@ -2787,8 +2686,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
|
|||
|
||||
- (NSString *) percentEncodedPassword
|
||||
{
|
||||
return [internal->_password stringByAddingPercentEncodingWithAllowedCharacters:
|
||||
[NSCharacterSet URLPasswordAllowedCharacterSet]];
|
||||
return [internal->_password
|
||||
stringByAddingPercentEncodingWithAllowedCharacters:
|
||||
[NSCharacterSet URLPasswordAllowedCharacterSet]];
|
||||
}
|
||||
|
||||
- (void) setPercentEncodedPassword: (NSString *)password
|
||||
|
@ -2798,8 +2698,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
|
|||
|
||||
- (NSString *) percentEncodedPath
|
||||
{
|
||||
return [internal->_path stringByAddingPercentEncodingWithAllowedCharacters:
|
||||
[NSCharacterSet URLPathAllowedCharacterSet]];
|
||||
return [internal->_path
|
||||
stringByAddingPercentEncodingWithAllowedCharacters:
|
||||
[NSCharacterSet URLPathAllowedCharacterSet]];
|
||||
}
|
||||
|
||||
- (void) setPercentEncodedPath: (NSString *)path
|
||||
|
@ -2874,8 +2775,10 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
|
|||
NSString *name = [i name];
|
||||
NSString *value = [i value];
|
||||
|
||||
name = [name _stringByAddingPercentEscapesForQuery];
|
||||
value = [value _stringByAddingPercentEscapesForQuery];
|
||||
name = [name stringByAddingPercentEncodingWithAllowedCharacters:
|
||||
queryItemCharSet];
|
||||
value = [value stringByAddingPercentEncodingWithAllowedCharacters:
|
||||
queryItemCharSet];
|
||||
ni = [NSURLQueryItem queryItemWithName: name
|
||||
value: value];
|
||||
[items addObject: ni];
|
||||
|
@ -2915,7 +2818,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
|
|||
- (NSString *) percentEncodedUser
|
||||
{
|
||||
return [internal->_user stringByAddingPercentEncodingWithAllowedCharacters:
|
||||
[NSCharacterSet URLUserAllowedCharacterSet]];
|
||||
[NSCharacterSet URLUserAllowedCharacterSet]];
|
||||
}
|
||||
|
||||
- (void) setPercentEncodedUser: (NSString *)user
|
||||
|
|
|
@ -373,7 +373,7 @@ typedef struct {
|
|||
NSInputStream *input;
|
||||
NSOutputStream *output;
|
||||
NSCachedURLResponse *cachedResponse;
|
||||
id <NSURLProtocolClient> client; // Not retained
|
||||
id <NSURLProtocolClient> client;
|
||||
NSURLRequest *request;
|
||||
NSString *in;
|
||||
NSString *out;
|
||||
|
@ -526,6 +526,7 @@ static NSURLProtocol *placeholder = nil;
|
|||
}
|
||||
DESTROY(this->cachedResponse);
|
||||
DESTROY(this->request);
|
||||
DESTROY(this->client);
|
||||
#if USE_ZLIB
|
||||
if (this->compressing == YES)
|
||||
{
|
||||
|
@ -596,7 +597,7 @@ static NSURLProtocol *placeholder = nil;
|
|||
{
|
||||
this->request = [request copy];
|
||||
this->cachedResponse = RETAIN(cachedResponse);
|
||||
this->client = client; // Not retained
|
||||
this->client = RETAIN(client);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
|
|
@ -114,12 +114,29 @@ typedef struct {
|
|||
{
|
||||
GSMimeHeader *h;
|
||||
|
||||
/* Remove existing headers matching the ones we are setting.
|
||||
*/
|
||||
e = [(NSArray*)headers objectEnumerator];
|
||||
while ((h = [e nextObject]) != nil)
|
||||
{
|
||||
NSString *n = [h namePreservingCase: YES];
|
||||
|
||||
[this->headers removeObjectForKey: n];
|
||||
}
|
||||
/* Set new headers, joining values where we have multiple headers
|
||||
* with the same name.
|
||||
*/
|
||||
e = [(NSArray*)headers objectEnumerator];
|
||||
while ((h = [e nextObject]) != nil)
|
||||
{
|
||||
NSString *n = [h namePreservingCase: YES];
|
||||
NSString *o = [this->headers objectForKey: n];
|
||||
NSString *v = [h fullValue];
|
||||
|
||||
if (nil != o)
|
||||
{
|
||||
n = [NSString stringWithFormat: @"%@, %@", o, n];
|
||||
}
|
||||
[self _setValue: v forHTTPHeaderField: n];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ int main()
|
|||
NSCalendar *cal;
|
||||
NSDate *date;
|
||||
NSDate *date2;
|
||||
NSDate *date3;
|
||||
NSDate *date4;
|
||||
|
||||
START_SET("NSCalendar 10.7 features")
|
||||
if (!NSCALENDAR_SUPPORTED)
|
||||
|
@ -48,7 +50,13 @@ int main()
|
|||
date2 = [comps date];
|
||||
|
||||
PASS_EQUAL(date, date2, "-[NSDateComponents date] returns the correct date");
|
||||
|
||||
|
||||
date3 = [NSDate dateWithString: @"2012-12-31 13:57:00 +0200"];
|
||||
[comps setTimeZone: [NSTimeZone timeZoneForSecondsFromGMT: 7200]];
|
||||
date4 = [cal dateFromComponents: comps];
|
||||
|
||||
PASS_EQUAL(date3, date4, "-[NSCalendar dateFromComponents:] respects the time zone");
|
||||
|
||||
RELEASE(comps);
|
||||
RELEASE(cal);
|
||||
|
||||
|
|
|
@ -39,14 +39,15 @@ int main()
|
|||
PASS(cookie == nil, "cookie without path returns nil");
|
||||
|
||||
dict = [NSDictionary dictionaryWithObject:
|
||||
@"S=calendar=R7tjDKqNB5L8YTZSvf29Bg;Expires=Wed, 09-Mar-2011 23:00:35 GMT"
|
||||
@"S=calendar=R7tjDKqNB5L8YTZSvf29Bg;Expires=Wed, 09-Mar-2011 23:00:35 GMT, "
|
||||
@"S=xxxxxxxx=R7tjDKqNB5L8YTZSvf29Bg;Expires=Thu, 10-Mar-2011 23:00:35 GMT"
|
||||
forKey: @"Set-Cookie"];
|
||||
|
||||
url = [NSURL URLWithString: @"http://www.google.com/calendar/feeds/default/"];
|
||||
cookies= [NSHTTPCookie cookiesWithResponseHeaderFields: dict forURL: url];
|
||||
TEST_FOR_CLASS(@"NSArray", cookies,
|
||||
"NSHTTPCookie +cookiesWithResponseHeaderFields: returns an NSArray");
|
||||
PASS([cookies count ] == 1, "cookies array contains a cookie");
|
||||
PASS([cookies count ] == 2, "cookies array contains two cookies");
|
||||
cookie = [cookies objectAtIndex: 0];
|
||||
PASS([[cookie name] isEqual: @"S"], "NSHTTPCookie returns proper name");
|
||||
PASS([[cookie value] isEqual: @"calendar=R7tjDKqNB5L8YTZSvf29Bg"],
|
||||
|
@ -56,6 +57,7 @@ int main()
|
|||
PASS(![cookie isSecure], "Cookie is not secure");
|
||||
PASS(![cookie isHTTPOnly], "Cookie is not http only");
|
||||
|
||||
cookies = [cookies subarrayWithRange: NSMakeRange(0, 1)];
|
||||
dict = [NSHTTPCookie requestHeaderFieldsWithCookies: cookies];
|
||||
PASS_EQUAL([dict objectForKey: @"Cookie"],
|
||||
@"S=calendar=R7tjDKqNB5L8YTZSvf29Bg",
|
||||
|
|
|
@ -26,7 +26,19 @@ int main()
|
|||
NSMutableArray *testObjs = [[NSMutableArray alloc] init];
|
||||
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
||||
|
||||
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"obj", @"key", nil];
|
||||
NSNotification *o1 = [NSNotification notificationWithName: @"hello"
|
||||
object: @"there"
|
||||
userInfo: info];
|
||||
NSNotification *o2 = [NSNotification notificationWithName: @"hello"
|
||||
object: @"there"
|
||||
userInfo: info];
|
||||
PASS([o1 hash] == [o2 hash], "equal notification hashes")
|
||||
PASS_EQUAL(o1, o2, "equal notifications")
|
||||
|
||||
test_alloc(@"NSNotification");
|
||||
|
||||
obj = [NSNotification new];
|
||||
[testObjs addObject: obj];
|
||||
test_NSObject(@"NSNotification", testObjs);
|
||||
|
|
|
@ -3,55 +3,93 @@
|
|||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSCharacterSet.h>
|
||||
|
||||
BOOL testUrlCharacterSetEncoding(
|
||||
NSString* decodedString,
|
||||
NSString* encodedString,
|
||||
NSCharacterSet* allowedCharacterSet)
|
||||
{
|
||||
NSString *testString
|
||||
= [decodedString stringByAddingPercentEncodingWithAllowedCharacters:
|
||||
allowedCharacterSet];
|
||||
// NSLog(@"String by adding percent, done. test=%@ decoded=%@", testString, decodedString);
|
||||
return [encodedString isEqualToString: testString];
|
||||
void testEncodeDecode(NSString* encoded, NSString* decoded, NSCharacterSet* charset, NSString* description){
|
||||
|
||||
NSString* encodeTest = [decoded stringByAddingPercentEncodingWithAllowedCharacters:charset];
|
||||
NSString* decodeTest = [encoded stringByRemovingPercentEncoding];
|
||||
|
||||
const char* encodeMsg = [[NSString stringWithFormat:@"Percent-Encode: %@", description] UTF8String];
|
||||
const char* decodeMsg = [[NSString stringWithFormat:@"Percent-Decode: %@", description] UTF8String];
|
||||
|
||||
PASS_EQUAL(encodeTest, encoded, "%s", encodeMsg);
|
||||
PASS_EQUAL(decodeTest, decoded, "%s", decodeMsg);
|
||||
}
|
||||
|
||||
int main (int argc, const char * argv[])
|
||||
{
|
||||
|
||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
|
||||
NSString *urlDecodedString = @"Only alphabetic characters should be allowed and not encoded. !@#$%^&*()_+-=";
|
||||
NSString *urlEncodedString =
|
||||
@"Only%20alphabetic%20characters%20should%20be%20allowed%20and%20not%20encoded%2E%20%21%40%23%24%25%5E%26%2A%28%29%5F%2B%2D%3D";
|
||||
NSCharacterSet *allowedCharacterSet = [NSCharacterSet alphanumericCharacterSet];
|
||||
PASS(testUrlCharacterSetEncoding(urlDecodedString, urlEncodedString, allowedCharacterSet), "alphanumericCharacterSet");
|
||||
|
||||
NSString *urlEncodedString = @"Only%20alphabetic%20characters%20should%20be%20allowed%20and%20not%20encoded%2E%20%21%40%23%24%25%5E%26%2A%28%29%5F%2B%2D%3D";
|
||||
testEncodeDecode(urlEncodedString, urlDecodedString, [NSCharacterSet alphanumericCharacterSet],
|
||||
@"Skip alphanumericCharacterSet 01");
|
||||
|
||||
|
||||
urlDecodedString = @"https://www.microsoft.com/en-us/!@#$%^&*()_";
|
||||
urlEncodedString = @"https://www.microsoft.com/en-us/!@%23$%25%5E&*()_";
|
||||
allowedCharacterSet = [NSCharacterSet URLFragmentAllowedCharacterSet];
|
||||
PASS(testUrlCharacterSetEncoding(urlDecodedString, urlEncodedString, allowedCharacterSet), "fragmentCharacterSet");
|
||||
|
||||
testEncodeDecode(urlEncodedString, urlDecodedString, [NSCharacterSet URLFragmentAllowedCharacterSet],
|
||||
@"Skip URLFragmentAllowedCharacterSet 02");
|
||||
|
||||
|
||||
urlDecodedString = @"All alphabetic characters should be encoded. Symbols should not be: !@#$%^&*()_+-=";
|
||||
urlEncodedString = @"%41%6C%6C %61%6C%70%68%61%62%65%74%69%63 %63%68%61%72%61%63%74%65%72%73 %73%68%6F%75%6C%64 %62%65 "
|
||||
@"%65%6E%63%6F%64%65%64. %53%79%6D%62%6F%6C%73 %73%68%6F%75%6C%64 %6E%6F%74 %62%65: !@#$%^&*()_+-=";
|
||||
allowedCharacterSet = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
|
||||
PASS(testUrlCharacterSetEncoding(urlDecodedString, urlEncodedString, allowedCharacterSet), "inverted");
|
||||
testEncodeDecode(urlEncodedString, urlDecodedString, [[NSCharacterSet alphanumericCharacterSet] invertedSet],
|
||||
@"Skip not alphanumericCharacterSet 03");
|
||||
|
||||
|
||||
urlDecodedString = @"Here are some Emojis: \U0001F601 \U0001F602 \U0001F638 Emojis done."; // Multibyte encoded characters
|
||||
urlEncodedString = @"Here%20are%20some%20Emojis:%20%F0%9F%98%81%20%F0%9F%98%82%20%F0%9F%98%B8%20Emojis%20done.";
|
||||
allowedCharacterSet = [NSCharacterSet URLFragmentAllowedCharacterSet];
|
||||
PASS(testUrlCharacterSetEncoding(urlDecodedString, urlEncodedString, allowedCharacterSet), "fragmentCharacterSet emojis");
|
||||
testEncodeDecode(urlEncodedString, urlDecodedString, [NSCharacterSet URLFragmentAllowedCharacterSet],
|
||||
@"Skip URLFragmentAllowedCharacterSet 04");
|
||||
|
||||
|
||||
urlDecodedString = @"\1";
|
||||
urlEncodedString = @"%01";
|
||||
allowedCharacterSet = [NSCharacterSet alphanumericCharacterSet];
|
||||
PASS(testUrlCharacterSetEncoding(urlDecodedString, urlEncodedString, allowedCharacterSet), "alphanumericCharacterSet");
|
||||
testEncodeDecode(urlEncodedString, urlDecodedString, [NSCharacterSet alphanumericCharacterSet],
|
||||
@"Skip URLFragmentAllowedCharacterSet 05");
|
||||
|
||||
|
||||
urlDecodedString = @"£";
|
||||
urlEncodedString = @"%C2%A3";
|
||||
testEncodeDecode(urlEncodedString, urlDecodedString, [NSCharacterSet alphanumericCharacterSet],
|
||||
@"Two-byte character 06");
|
||||
|
||||
|
||||
urlDecodedString = @"€";
|
||||
urlEncodedString = @"%E2%82%AC";
|
||||
testEncodeDecode(urlEncodedString, urlDecodedString, [NSCharacterSet alphanumericCharacterSet],
|
||||
@"Three-byte character 07");
|
||||
|
||||
|
||||
urlDecodedString = @"𐍈";
|
||||
urlEncodedString = @"%F0%90%8D%88";
|
||||
testEncodeDecode(urlEncodedString, urlDecodedString, [NSCharacterSet alphanumericCharacterSet],
|
||||
@"Four-byte character 08");
|
||||
|
||||
|
||||
//check full string encoding and decoding
|
||||
urlDecodedString = @"0123456789 AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz _-~`!#$%&'()*+,/:;=?@[]™…©®£ƒ‰¥§";
|
||||
urlEncodedString = @"%30%31%32%33%34%35%36%37%38%39%20%41%61%42%62%43%63%44%64%45%65%46%66%47%67%48%68%49%69%4A%6A%4B%6B%4C%6C%4D%6D%4E%6E%4F%6F%50%70%51%71%52%72%53%73%54%74%55%75%56%76%57%77%58%78%59%79%5A%7A%20%5F%2D%7E%60%21%23%24%25%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D%E2%84%A2%E2%80%A6%C2%A9%C2%AE%C2%A3%C6%92%E2%80%B0%C2%A5%C2%A7";
|
||||
testEncodeDecode(urlEncodedString, urlDecodedString, [[NSCharacterSet characterSetWithCharactersInString:urlDecodedString] invertedSet],
|
||||
@"All characters in string 09");
|
||||
|
||||
|
||||
//check decoding of string with an unencoded part at the beginning
|
||||
NSString* asIsString = @"0123456789 AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz _-~`!#$&'()*+,/:;=?@[]™…©®£ƒ‰¥§";
|
||||
urlDecodedString = [asIsString stringByAppendingString:urlDecodedString];
|
||||
urlEncodedString = [asIsString stringByAppendingString:urlEncodedString];
|
||||
PASS_EQUAL([urlEncodedString stringByRemovingPercentEncoding], urlDecodedString, "Percent-encoded string decoding 10");
|
||||
|
||||
|
||||
//check decoding of string with the encoded part in the middle
|
||||
urlDecodedString = [urlDecodedString stringByAppendingString:asIsString];
|
||||
urlEncodedString = [urlEncodedString stringByAppendingString:asIsString];
|
||||
PASS_EQUAL([urlEncodedString stringByRemovingPercentEncoding], urlDecodedString, "Percent-encoded string decoding 11");
|
||||
|
||||
|
||||
urlDecodedString = @"All alphabetic characters should be encoded. Symbols should not be: !@#$%^&*()_+-=";
|
||||
urlEncodedString = @"%41%6C%6C %61%6C%70%68%61%62%65%74%69%63 %63%68%61%72%61%63%74%65%72%73 %73%68%6F%75%6C%64 %62%65 "
|
||||
@"%65%6E%63%6F%64%65%64. %53%79%6D%62%6F%6C%73 %73%68%6F%75%6C%64 %6E%6F%74 %62%65: !@#$%^&*()_+-=";
|
||||
NSString *result = [urlEncodedString stringByRemovingPercentEncoding];
|
||||
PASS([urlDecodedString isEqualToString: result], "stringByRemovingPercentEncoding");
|
||||
// NSLog(@"Result = \"%@\",\ndecodedString = \"%@\",\nencodedString = \"%@\"", result, urlDecodedString, urlEncodedString);
|
||||
[pool drain];
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -29,9 +29,12 @@ int main()
|
|||
TEST_FOR_CLASS(@"NSURL", [NSURL URLWithString: @"http://www.w3.org/"],
|
||||
"NSURL +URLWithString: returns an NSURL");
|
||||
|
||||
url = [NSURL URLWithString: nil];
|
||||
PASS(nil == url, "A nil string result in nil URL");
|
||||
|
||||
str = [NSString stringWithCharacters: bad length: sizeof(bad)/sizeof(*bad)];
|
||||
url = [NSURL URLWithString: str];
|
||||
PASS(nil == url, "Bad characters result in nil");
|
||||
PASS(nil == url, "Bad characters result in nil URL");
|
||||
|
||||
str = [NSString stringWithCharacters: &u length: 1];
|
||||
url = [NSURL fileURLWithPath: str];
|
||||
|
@ -292,17 +295,20 @@ GSPathHandling("right");
|
|||
PASS(nil == [url host], "host");
|
||||
PASS(nil == [url user], "user");
|
||||
PASS(nil == [url password], "password");
|
||||
PASS([@"/pathtofile;parameters?query#anchor"
|
||||
isEqual: [url resourceSpecifier]], "resourceSpecifier");
|
||||
PASS([@"/pathtofile" isEqual: [url path]], "path");
|
||||
PASS([@"query" isEqual: [url query]], "query");
|
||||
PASS([@"parameters" isEqual: [url parameterString]], "parameterString");
|
||||
PASS([@"anchor" isEqual: [url fragment]], "fragment");
|
||||
PASS([@"file:///pathtofile;parameters?query#anchor"
|
||||
isEqual: [url absoluteString]], "absoluteString");
|
||||
PASS([@"/pathtofile" isEqual: [url relativePath]], "relativePath");
|
||||
PASS([@"file:///pathtofile;parameters?query#anchor"
|
||||
isEqual: [url description]], "description");
|
||||
PASS_EQUAL([url resourceSpecifier],
|
||||
@"/pathtofile;parameters?query#anchor",
|
||||
"resourceSpecifier");
|
||||
PASS_EQUAL([url path], @"/pathtofile", "path");
|
||||
PASS_EQUAL([url query], @"query", "query");
|
||||
PASS_EQUAL([url parameterString], @"parameters", "parameterString");
|
||||
PASS_EQUAL([url fragment], @"anchor", "fragment");
|
||||
PASS_EQUAL([url absoluteString],
|
||||
@"file:///pathtofile;parameters?query#anchor",
|
||||
"absoluteString");
|
||||
PASS_EQUAL([url relativePath], @"/pathtofile", "relativePath");
|
||||
PASS_EQUAL([url description],
|
||||
@"file:///pathtofile;parameters?query#anchor",
|
||||
"description");
|
||||
|
||||
url = [NSURL URLWithString: @"file:///pathtofile; parameters? query #anchor"]; // can't initialize with spaces (must be %20)
|
||||
PASS(nil == url, "url with spaces");
|
||||
|
|
55
Tests/base/NSURL/charsets.m
Normal file
55
Tests/base/NSURL/charsets.m
Normal file
|
@ -0,0 +1,55 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import "Testing.h"
|
||||
#import "ObjectTesting.h"
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
START_SET("URL character sets")
|
||||
NSMutableString *m = [NSMutableString string];
|
||||
NSDictionary *sets;
|
||||
NSEnumerator *enumerator;
|
||||
NSString *key;
|
||||
|
||||
sets = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"!$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~",
|
||||
@"URLFragmentAllowedCharacterSet",
|
||||
@"!$&'()*+,-.0123456789:;=ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~",
|
||||
@"URLHostAllowedCharacterSet",
|
||||
@"!$&'()*+,-.0123456789;=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~",
|
||||
@"URLPasswordAllowedCharacterSet",
|
||||
@"!$&'()*+,-./0123456789:=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~",
|
||||
@"URLPathAllowedCharacterSet",
|
||||
@"!$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~",
|
||||
@"URLQueryAllowedCharacterSet",
|
||||
@"!$&'()*+,-.0123456789;=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~",
|
||||
@"URLUserAllowedCharacterSet",
|
||||
nil];
|
||||
enumerator = [sets keyEnumerator];
|
||||
while (nil != (key = [enumerator nextObject]))
|
||||
{
|
||||
NSString *expect = [sets objectForKey: key];
|
||||
const char *name = [key UTF8String];
|
||||
NSCharacterSet *set;
|
||||
unichar c;
|
||||
|
||||
set = (NSCharacterSet*)[[NSCharacterSet class] performSelector:
|
||||
NSSelectorFromString(key)];
|
||||
[m setString: @""];
|
||||
for (c = 0; c < 128; c++)
|
||||
{
|
||||
if ([set characterIsMember: c])
|
||||
{
|
||||
NSString *s;
|
||||
|
||||
s = [[NSString alloc] initWithCharacters: &c length: 1];
|
||||
[m appendString: s];
|
||||
RELEASE(s);
|
||||
}
|
||||
}
|
||||
PASS_EQUAL(m, expect, "%s as string", name)
|
||||
}
|
||||
|
||||
END_SET("URL character sets")
|
||||
return 0;
|
||||
}
|
23
configure
vendored
23
configure
vendored
|
@ -670,7 +670,6 @@ HAVE_PTS_STREAM_MODULES
|
|||
OBJCFLAGS
|
||||
HAVE_OBJC_SYNC_ENTER
|
||||
BASE_NATIVE_OBJC_EXCEPTIONS
|
||||
GS_MIXEDABI
|
||||
GS_NONFRAGILE
|
||||
HAVE_BLOCKS
|
||||
OBJC2RUNTIME
|
||||
|
@ -794,7 +793,6 @@ with_default_config
|
|||
with_installation_domain
|
||||
enable_largefile
|
||||
enable_nxconstantstring
|
||||
enable_mixedabi
|
||||
enable_bfd
|
||||
enable_procfs
|
||||
enable_procfs_psinfo
|
||||
|
@ -1477,9 +1475,6 @@ Optional Features:
|
|||
--disable-largefile omit support for large files
|
||||
--enable-nxconstantstring
|
||||
Enables the use of the NXConstantString class for old compilers.
|
||||
--disable-mixedabi
|
||||
Disables the combined use of fragile and nonfragile ABI so that base
|
||||
can be built taking full advantage of the nonfragile ABI.
|
||||
--enable-bfd
|
||||
Enables the use of libbfd to provide symbolic stack traces.
|
||||
Enabling this option provides support for symbolic stack traces
|
||||
|
@ -2732,8 +2727,9 @@ fi
|
|||
if test -z "$LIBRARY_COMBO"; then
|
||||
LIBRARY_COMBO=`gnustep-config --variable=LIBRARY_COMBO 2>&5`
|
||||
fi
|
||||
OBJC_RUNTIME_LIB=`echo $LIBRARY_COMBO | tr '-' ' ' | awk '{print $1}'`
|
||||
|
||||
if test "$OBJC_RUNTIME_LIB" = "ng"; then
|
||||
if test "$OBJC_RUNTIME_LIB" = "ng" -o "$OBJC_RUNTIME_LIB" = "apple"; then
|
||||
nonfragile=yes
|
||||
BASE_NONFRAGILE_ABI=1
|
||||
else
|
||||
|
@ -6008,7 +6004,6 @@ esac
|
|||
#--------------------------------------------------------------------
|
||||
# Set Apple/Darwin/OSX/NeXT information for other tests
|
||||
#--------------------------------------------------------------------
|
||||
OBJC_RUNTIME_LIB=`echo $LIBRARY_COMBO | tr '-' ' ' | awk '{print $1}'`
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the Objective-C runtime" >&5
|
||||
$as_echo_n "checking the Objective-C runtime... " >&6; }
|
||||
if test "$OBJC_RUNTIME_LIB" = "nx" -o "$OBJC_RUNTIME_LIB" = "apple"; then
|
||||
|
@ -8101,7 +8096,6 @@ fi
|
|||
# Don't revert any Objective-C flags as they are used in the next test
|
||||
|
||||
GS_NONFRAGILE=0
|
||||
GS_MIXEDABI=0
|
||||
if test "$nonfragile" = "yes"; then
|
||||
saved_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $OBJCFLAGS -x objective-c"
|
||||
|
@ -8126,18 +8120,6 @@ fi
|
|||
CPPFLAGS="$saved_CPPFLAGS"
|
||||
if test $non_fragile = yes; then
|
||||
GS_NONFRAGILE=1
|
||||
if test "$OBJC_RUNTIME_LIB" != "ng"; then
|
||||
# Check whether --enable-mixedabi was given.
|
||||
if test "${enable_mixedabi+set}" = set; then :
|
||||
enableval=$enable_mixedabi;
|
||||
else
|
||||
enable_mixedabi=yes
|
||||
fi
|
||||
|
||||
if test $enable_mixedabi = yes; then
|
||||
GS_MIXEDABI=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $non_fragile" >&5
|
||||
$as_echo "$non_fragile" >&6; }
|
||||
|
@ -8145,7 +8127,6 @@ fi
|
|||
|
||||
|
||||
|
||||
|
||||
# Don't revert any Objective-C flags as they are used in the next test
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
|
|
16
configure.ac
16
configure.ac
|
@ -89,8 +89,9 @@ fi
|
|||
if test -z "$LIBRARY_COMBO"; then
|
||||
LIBRARY_COMBO=`gnustep-config --variable=LIBRARY_COMBO 2>&5`
|
||||
fi
|
||||
OBJC_RUNTIME_LIB=`echo $LIBRARY_COMBO | tr '-' ' ' | awk '{print $1}'`
|
||||
|
||||
if test "$OBJC_RUNTIME_LIB" = "ng"; then
|
||||
if test "$OBJC_RUNTIME_LIB" = "ng" -o "$OBJC_RUNTIME_LIB" = "apple"; then
|
||||
nonfragile=yes
|
||||
BASE_NONFRAGILE_ABI=1
|
||||
else
|
||||
|
@ -1254,7 +1255,6 @@ esac
|
|||
#--------------------------------------------------------------------
|
||||
# Set Apple/Darwin/OSX/NeXT information for other tests
|
||||
#--------------------------------------------------------------------
|
||||
OBJC_RUNTIME_LIB=`echo $LIBRARY_COMBO | tr '-' ' ' | awk '{print $1}'`
|
||||
AC_MSG_CHECKING(the Objective-C runtime)
|
||||
if test "$OBJC_RUNTIME_LIB" = "nx" -o "$OBJC_RUNTIME_LIB" = "apple"; then
|
||||
AC_MSG_RESULT(NeXT)
|
||||
|
@ -2017,7 +2017,6 @@ AC_SUBST(HAVE_BLOCKS)
|
|||
# Don't revert any Objective-C flags as they are used in the next test
|
||||
|
||||
GS_NONFRAGILE=0
|
||||
GS_MIXEDABI=0
|
||||
if test "$nonfragile" = "yes"; then
|
||||
saved_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $OBJCFLAGS -x objective-c"
|
||||
|
@ -2029,21 +2028,10 @@ if test "$nonfragile" = "yes"; then
|
|||
CPPFLAGS="$saved_CPPFLAGS"
|
||||
if test $non_fragile = yes; then
|
||||
GS_NONFRAGILE=1
|
||||
if test "$OBJC_RUNTIME_LIB" != "ng"; then
|
||||
AC_ARG_ENABLE(mixedabi,
|
||||
[ --disable-mixedabi
|
||||
Disables the combined use of fragile and nonfragile ABI so that base
|
||||
can be built taking full advantage of the nonfragile ABI.],,
|
||||
enable_mixedabi=yes)
|
||||
if test $enable_mixedabi = yes; then
|
||||
GS_MIXEDABI=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT($non_fragile)
|
||||
fi
|
||||
AC_SUBST(GS_NONFRAGILE)
|
||||
AC_SUBST(GS_MIXEDABI)
|
||||
|
||||
|
||||
# Don't revert any Objective-C flags as they are used in the next test
|
||||
|
|
Loading…
Reference in a new issue