mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 00:30:53 +00:00
Merge pull request #38 from gnustep/nsstring_and_nscharacterset_changes
NSString and NSCharacterSet changes
This commit is contained in:
commit
6377b93726
13 changed files with 439 additions and 2 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,4 +1,16 @@
|
|||
2019-04-12 Gregory John Casamento <greg.casamento@gmail.com>
|
||||
|
||||
* Source/NSCharacterSet.m: Added declarations/implementations for
|
||||
URL*AllowedCharacterSet.
|
||||
* Headers/NSCharacterSet.h: Added declarations here for
|
||||
URL*AllowedCharacterSet
|
||||
* Source/CharSets/*: Added headers to define new charactersets.
|
||||
* Source/NSString.m: Added methods stringByRemovingPercentEncoding/
|
||||
stringByAddingPercentEncodingWithAllowedCharacterSet:
|
||||
* Header/NSString.h: Added declrations for methods mentioned above.
|
||||
|
||||
2019-03-29 Igor Zhukov <fsb4000@yandex.ru>
|
||||
|
||||
* Source/NSDateFormatter.m:
|
||||
* configure:
|
||||
* configure.ac:
|
||||
|
|
|
@ -98,6 +98,36 @@ extern "C" {
|
|||
* 0x000A and 0x000D and nextline 0x0085 character.
|
||||
*/
|
||||
+ (id) newlineCharacterSet;
|
||||
|
||||
/**
|
||||
* Returns allowed characers for URL fragment component.
|
||||
*/
|
||||
+ (id) URLFragmentAllowedCharacterSet;
|
||||
|
||||
/**
|
||||
* Returns allowed characers for URL host component.
|
||||
*/
|
||||
+ (id) URLHostAllowedCharacterSet;
|
||||
|
||||
/**
|
||||
* Returns allowed characers for URL password component.
|
||||
*/
|
||||
+ (id) URLPasswordAllowedCharacterSet;
|
||||
|
||||
/**
|
||||
* Returns allowed characers for URL path component.
|
||||
*/
|
||||
+ (id) URLPathAllowedCharacterSet;
|
||||
|
||||
/**
|
||||
* Returns allowed characers for URL query component.
|
||||
*/
|
||||
+ (id) URLQueryAllowedCharacterSet;
|
||||
|
||||
/**
|
||||
* Returns allowed characers for URL USER component.
|
||||
*/
|
||||
+ (id) URLUserAllowedCharacterSet;
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
@ -802,6 +802,11 @@ typedef NSUInteger NSStringEncodingConversionOptions;
|
|||
- (const char *)UTF8String;
|
||||
#endif
|
||||
|
||||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_9,GS_API_LATEST)
|
||||
- (NSString *) stringByAddingPercentEncodingWithAllowedCharacters: (NSCharacterSet *)aSet;
|
||||
- (NSString *) stringByRemovingPercentEncoding;
|
||||
#endif
|
||||
|
||||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_3,GS_API_LATEST)
|
||||
/** Not implemented */
|
||||
- (void) getParagraphStart: (NSUInteger *)startIndex
|
||||
|
|
18
Source/CharSets/URLFragmentAllowedCharSet.h
Normal file
18
Source/CharSets/URLFragmentAllowedCharSet.h
Normal file
File diff suppressed because one or more lines are too long
18
Source/CharSets/URLHostAllowedCharSet.h
Normal file
18
Source/CharSets/URLHostAllowedCharSet.h
Normal file
File diff suppressed because one or more lines are too long
18
Source/CharSets/URLPasswordAllowedCharSet.h
Normal file
18
Source/CharSets/URLPasswordAllowedCharSet.h
Normal file
File diff suppressed because one or more lines are too long
18
Source/CharSets/URLPathAllowedCharSet.h
Normal file
18
Source/CharSets/URLPathAllowedCharSet.h
Normal file
File diff suppressed because one or more lines are too long
18
Source/CharSets/URLQueryAllowedCharSet.h
Normal file
18
Source/CharSets/URLQueryAllowedCharSet.h
Normal file
File diff suppressed because one or more lines are too long
18
Source/CharSets/URLUserAllowedCharSet.h
Normal file
18
Source/CharSets/URLUserAllowedCharSet.h
Normal file
File diff suppressed because one or more lines are too long
|
@ -49,6 +49,12 @@
|
|||
#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
|
||||
|
@ -537,7 +543,7 @@
|
|||
|
||||
|
||||
/* A simple array for caching standard bitmap sets */
|
||||
#define MAX_STANDARD_SETS 15
|
||||
#define MAX_STANDARD_SETS 21
|
||||
static NSCharacterSet *cache_set[MAX_STANDARD_SETS];
|
||||
static Class abstractClass = nil;
|
||||
static Class abstractMutableClass = nil;
|
||||
|
@ -833,6 +839,48 @@ static Class concreteMutableClass = nil;
|
|||
return nil;
|
||||
}
|
||||
|
||||
+ (id) URLFragmentAllowedCharacterSet
|
||||
{
|
||||
return [self _staticSet: urlFragmentAllowedCharSet
|
||||
length: sizeof(urlFragmentAllowedCharSet)
|
||||
number: 15];
|
||||
}
|
||||
|
||||
+ (id) URLPasswordAllowedCharacterSet
|
||||
{
|
||||
return [self _staticSet: urlPasswordAllowedCharSet
|
||||
length: sizeof(urlPasswordAllowedCharSet)
|
||||
number: 16];
|
||||
}
|
||||
|
||||
+ (id) URLPathAllowedCharacterSet
|
||||
{
|
||||
return [self _staticSet: urlPathAllowedCharSet
|
||||
length: sizeof(urlPathAllowedCharSet)
|
||||
number: 17];
|
||||
}
|
||||
|
||||
+ (id) URLQueryAllowedCharacterSet
|
||||
{
|
||||
return [self _staticSet: urlQueryAllowedCharSet
|
||||
length: sizeof(urlQueryAllowedCharSet)
|
||||
number: 18];
|
||||
}
|
||||
|
||||
+ (id) URLUserAllowedCharacterSet
|
||||
{
|
||||
return [self _staticSet: urlUserAllowedCharSet
|
||||
length: sizeof(urlUserAllowedCharSet)
|
||||
number: 19];
|
||||
}
|
||||
|
||||
+ (id) URLHostAllowedCharacterSet
|
||||
{
|
||||
return [self _staticSet: urlHostAllowedCharSet
|
||||
length: sizeof(urlHostAllowedCharSet)
|
||||
number: 20];
|
||||
}
|
||||
|
||||
- (NSData*) bitmapRepresentation
|
||||
{
|
||||
BOOL (*imp)(id, SEL, unichar);
|
||||
|
@ -1118,6 +1166,36 @@ static Class concreteMutableClass = nil;
|
|||
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
|
||||
}
|
||||
|
||||
+ (id) URLFragmentAllowedCharacterSet;
|
||||
{
|
||||
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
|
||||
}
|
||||
|
||||
+ (id) URLHostAllowedCharacterSet;
|
||||
{
|
||||
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
|
||||
}
|
||||
|
||||
+ (id) URLPasswordAllowedCharacterSet;
|
||||
{
|
||||
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
|
||||
}
|
||||
|
||||
+ (id) URLPathAllowedCharacterSet;
|
||||
{
|
||||
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
|
||||
}
|
||||
|
||||
+ (id) URLQueryAllowedCharacterSet;
|
||||
{
|
||||
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
|
||||
}
|
||||
|
||||
+ (id) URLUserAllowedCharacterSet
|
||||
{
|
||||
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
|
||||
}
|
||||
|
||||
+ (id) characterSetWithCharactersInString: (NSString*)aString
|
||||
{
|
||||
NSMutableCharacterSet *ms;
|
||||
|
|
|
@ -276,6 +276,42 @@ GSPathHandling(const char *mode)
|
|||
}
|
||||
}
|
||||
|
||||
// Test if the digit is hex..
|
||||
inline int ishex(int x)
|
||||
{
|
||||
return
|
||||
(x >= '0' && x <= '9') ||
|
||||
(x >= 'a' && x <= 'f') ||
|
||||
(x >= 'A' && x <= 'F');
|
||||
}
|
||||
|
||||
// URL decoding...
|
||||
int urldecode(const char *s, char *dec)
|
||||
{
|
||||
char *o;
|
||||
const char *end = s + strlen(s);
|
||||
int c;
|
||||
int cx;
|
||||
for (o = dec; s <= end; o++)
|
||||
{
|
||||
c = *s++;
|
||||
cx = c; // preserve original value if we are not to decode
|
||||
if (c == '%' && (!ishex(*s++) ||
|
||||
!ishex(*s++) ||
|
||||
!sscanf(s - 2, "%2x", &c)))
|
||||
{
|
||||
c = cx; // reset c to original value.
|
||||
s--;
|
||||
}
|
||||
if (dec)
|
||||
{
|
||||
*o = c;
|
||||
}
|
||||
}
|
||||
|
||||
return o - dec;
|
||||
}
|
||||
|
||||
#define GSPathHandlingRight() \
|
||||
((pathHandling == PH_DO_THE_RIGHT_THING) ? YES : NO)
|
||||
#define GSPathHandlingUnix() \
|
||||
|
@ -1886,6 +1922,70 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
|
|||
}
|
||||
}
|
||||
|
||||
- (NSString *) stringByAddingPercentEncodingWithAllowedCharacters: (NSCharacterSet *)aSet
|
||||
{
|
||||
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)
|
||||
{
|
||||
unichar c = src[spos++];
|
||||
unsigned int hi;
|
||||
unsigned int lo;
|
||||
|
||||
if([aSet characterIsMember: c]) // if the character is in the allowed set, put it in
|
||||
{
|
||||
dst[dpos++] = c;
|
||||
}
|
||||
else // if not, then encode it...
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
s = [[NSString alloc] initWithBytes: dst
|
||||
length: dpos
|
||||
encoding: NSUTF8StringEncoding];
|
||||
NSZoneFree(NSDefaultMallocZone(), dst);
|
||||
IF_NO_GC([s autorelease];)
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
- (NSString *) stringByRemovingPercentEncoding
|
||||
{
|
||||
NSData *data = [self dataUsingEncoding: NSUTF8StringEncoding];
|
||||
NSString *result = nil;
|
||||
char *s = (char *)[data bytes];
|
||||
NSUInteger slen = 0;
|
||||
char *o = NULL;
|
||||
|
||||
// Allocate memory...
|
||||
slen = strlen(s);
|
||||
o = (char *)NSZoneMalloc(NSDefaultMallocZone(), slen);
|
||||
|
||||
// Decode...
|
||||
urldecode(s,o);
|
||||
|
||||
// Free up temporary space...
|
||||
result = [NSString stringWithCString: o encoding: NSUTF8StringEncoding];
|
||||
NSZoneFree(NSDefaultMallocZone(), o);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new ASCII string which is a representation of the receiver
|
||||
* in which characters are escaped where necessary in order to produce a
|
||||
|
|
|
@ -88,8 +88,53 @@ int main()
|
|||
![theSet characterIsMember: '#'],
|
||||
"Check custom set");
|
||||
|
||||
theSet = [NSCharacterSet URLFragmentAllowedCharacterSet];
|
||||
NSString *setString = @"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ?/:@-._~!$&'()*+,=";
|
||||
NSUInteger i = 0;
|
||||
BOOL p = YES;
|
||||
for(i = 0; i < [setString length]; i++)
|
||||
{
|
||||
char c = [setString characterAtIndex: i];
|
||||
if([theSet characterIsMember: c] == NO) // , [msg cStringUsingEncoding: NSUTF8Encoding]);
|
||||
{
|
||||
NSLog(@"%c is not in set", c);
|
||||
PASS(NO,"URLFragmentAllowedCharacterSet char not found");
|
||||
p = NO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!p)
|
||||
{
|
||||
PASS(YES, "URLFragmentAllowedCharacterSet passwed");
|
||||
}
|
||||
/*
|
||||
PASS(//[theSet characterIsMember: 'A'] &&
|
||||
//[theSet characterIsMember: 'Z'] &&
|
||||
//[theSet characterIsMember: 'a'] &&
|
||||
//[theSet characterIsMember: 'z'] &&
|
||||
//[theSet characterIsMember: '9'] &&
|
||||
// [theSet characterIsMember: '0'] &&
|
||||
[theSet characterIsMember: '?'] &&
|
||||
[theSet characterIsMember: '/ '] &&
|
||||
[theSet characterIsMember: ':'] &&
|
||||
[theSet characterIsMember: '@ '] &&
|
||||
[theSet characterIsMember: '-'] &&
|
||||
[theSet characterIsMember: '.'] &&
|
||||
[theSet characterIsMember: '_'] &&
|
||||
[theSet characterIsMember: '~'] &&
|
||||
[theSet characterIsMember: '!'] &&
|
||||
[theSet characterIsMember: '$ '] &&
|
||||
[theSet characterIsMember: '&'] &&
|
||||
// [theSet characterIsMember: '\''] &&
|
||||
[theSet characterIsMember: '('] &&
|
||||
[theSet characterIsMember: ')'] &&
|
||||
[theSet characterIsMember: '*'] &&
|
||||
[theSet characterIsMember: '+'] &&
|
||||
[theSet characterIsMember: ','] &&
|
||||
[theSet characterIsMember: ';'] &&
|
||||
[theSet characterIsMember: '='],
|
||||
"Check some characters from URLFramgmentAllowedCharacterSet"); */
|
||||
|
||||
[arp release]; arp = nil;
|
||||
return 0;
|
||||
}
|
||||
|
|
59
Tests/base/NSString/test09.m
Normal file
59
Tests/base/NSString/test09.m
Normal file
|
@ -0,0 +1,59 @@
|
|||
#import "ObjectTesting.h"
|
||||
#import <Foundation/NSAutoreleasePool.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSCharacterSet.h>
|
||||
|
||||
BOOL testUrlCharacterSetEncoding(NSString* decodedString, NSString* encodedString, NSCharacterSet* allowedCharacterSet)
|
||||
{
|
||||
NSLog(@"String by adding percent");
|
||||
NSString* testString = [decodedString stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
|
||||
NSLog(@"String by adding percent, done. test=%@ decoded=%@", testString, decodedString);
|
||||
return [encodedString isEqualToString: testString];
|
||||
}
|
||||
|
||||
int main (int argc, const char * argv[])
|
||||
{
|
||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSLog(@"Test1");
|
||||
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");
|
||||
|
||||
NSLog(@"Test2");
|
||||
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");
|
||||
|
||||
NSLog(@"Test3");
|
||||
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");
|
||||
|
||||
NSLog(@"Test4");
|
||||
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");
|
||||
|
||||
NSLog(@"Test5");
|
||||
urlDecodedString = @"\1";
|
||||
urlEncodedString = @"%01";
|
||||
allowedCharacterSet = [NSCharacterSet alphanumericCharacterSet];
|
||||
PASS(testUrlCharacterSetEncoding(urlDecodedString, urlEncodedString, allowedCharacterSet), "alphanumericCharacterSet");
|
||||
|
||||
NSLog(@"Test5");
|
||||
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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue