mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 00:41:02 +00:00
merge in latest bas64 changes
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/branches/bitmarkets_changes@38639 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
6d4af68092
commit
490a0bcbb2
3 changed files with 160 additions and 2 deletions
|
@ -1,3 +1,9 @@
|
|||
2015-06-14 Riccardo Mottola <rm@gnu.org>
|
||||
|
||||
* Headers/Foundation/NSData.h
|
||||
* Source/NSData.m
|
||||
base64EncodedDataWithOptions, base64EncodedStringWithOptions: first implementation
|
||||
|
||||
2015-06-08 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSData.m: be strict about '=' padding only occurring at end
|
||||
|
|
109
Source/NSData.m
109
Source/NSData.m
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
Copyright (C) 1995, 1996, 1997, 2000, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-2015 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: March 1995
|
||||
|
@ -147,6 +147,88 @@ decodebase64(unsigned char *dst, const unsigned char *src)
|
|||
dst[2] = ((src[2] & 0x03) << 6) | (src[3] & 0x3F);
|
||||
}
|
||||
|
||||
static char b64[]
|
||||
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
static NSUInteger
|
||||
encodebase64(unsigned char **dstRef, const unsigned char *src, NSUInteger length, NSDataBase64EncodingOptions options)
|
||||
{
|
||||
unsigned char *dst;
|
||||
NSUInteger dIndex = 0;
|
||||
NSUInteger dIndexNoNewLines = 0;
|
||||
NSUInteger sIndex;
|
||||
NSUInteger lineLength;
|
||||
NSUInteger destLen;
|
||||
|
||||
lineLength = 0;
|
||||
if (options & NSDataBase64Encoding64CharacterLineLength)
|
||||
lineLength = 64;
|
||||
else if (options & NSDataBase64Encoding76CharacterLineLength)
|
||||
lineLength = 76;
|
||||
|
||||
/* if no EndLine options are set but a line length is given, CR+LF is implied */
|
||||
if (lineLength && !(options & NSDataBase64EncodingEndLineWithCarriageReturn) && !(options & NSDataBase64EncodingEndLineWithLineFeed))
|
||||
{
|
||||
options |= NSDataBase64EncodingEndLineWithCarriageReturn;
|
||||
options |= NSDataBase64EncodingEndLineWithLineFeed;
|
||||
}
|
||||
|
||||
/* estimate destination length */
|
||||
destLen = 4 * ((length + 2) / 3);
|
||||
/* we need to take in account line-endings */
|
||||
if (lineLength)
|
||||
{
|
||||
if (options & (NSDataBase64EncodingEndLineWithCarriageReturn | NSDataBase64EncodingEndLineWithLineFeed))
|
||||
destLen += (destLen / lineLength)*2;
|
||||
else
|
||||
destLen += (destLen / lineLength);
|
||||
}
|
||||
|
||||
#if GS_WITH_GC
|
||||
dst = NSAllocateCollectable(destLen, 0);
|
||||
#else
|
||||
dst = NSZoneMalloc(NSDefaultMallocZone(), destLen);
|
||||
#endif
|
||||
|
||||
for (sIndex = 0; sIndex < length; sIndex += 3)
|
||||
{
|
||||
int c0 = src[sIndex];
|
||||
int c1 = (sIndex+1 < length) ? src[sIndex+1] : 0;
|
||||
int c2 = (sIndex+2 < length) ? src[sIndex+2] : 0;
|
||||
|
||||
dst[dIndex++] = b64[(c0 >> 2) & 077];
|
||||
dst[dIndex++] = b64[((c0 << 4) & 060) | ((c1 >> 4) & 017)];
|
||||
dst[dIndex++] = b64[((c1 << 2) & 074) | ((c2 >> 6) & 03)];
|
||||
dst[dIndex++] = b64[c2 & 077];
|
||||
dIndexNoNewLines += 4;
|
||||
if (lineLength && !(dIndexNoNewLines % lineLength) )
|
||||
{
|
||||
if (options & NSDataBase64EncodingEndLineWithCarriageReturn)
|
||||
dst[dIndex++] = '\r';
|
||||
if (options & NSDataBase64EncodingEndLineWithLineFeed)
|
||||
dst[dIndex++] = '\n';
|
||||
}
|
||||
}
|
||||
|
||||
/* If len was not a multiple of 3, then we have encoded too
|
||||
* many characters. Adjust appropriately.
|
||||
*/
|
||||
if (sIndex == length + 1)
|
||||
{
|
||||
/* There were only 2 bytes in that last group */
|
||||
dst[dIndex - 1] = '=';
|
||||
}
|
||||
else if (sIndex == length + 2)
|
||||
{
|
||||
/* There was only 1 byte in that last group */
|
||||
dst[dIndex - 1] = '=';
|
||||
dst[dIndex - 2] = '=';
|
||||
}
|
||||
|
||||
*dstRef = dst;
|
||||
return dIndex;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
readContentsOfFile(NSString* path, void** buf, off_t* len, NSZone* zone)
|
||||
{
|
||||
|
@ -221,7 +303,7 @@ readContentsOfFile(NSString* path, void** buf, off_t* len, NSZone* zone)
|
|||
if (fileLength == 0)
|
||||
{
|
||||
unsigned char buf[BUFSIZ];
|
||||
|
||||
|
||||
/*
|
||||
* Special case ... a file of length zero may be a named pipe or some
|
||||
* file in the /proc filesystem, which will return us data if we read
|
||||
|
@ -959,6 +1041,29 @@ failure:
|
|||
return [NSData dataWithBytesNoCopy: buffer length: aRange.length];
|
||||
}
|
||||
|
||||
- (NSData *)base64EncodedDataWithOptions:(NSDataBase64EncodingOptions)options
|
||||
{
|
||||
void *srcBytes = (void*)[self bytes];
|
||||
NSUInteger length = [self length];
|
||||
NSUInteger resLen;
|
||||
unsigned char *resBytes;
|
||||
|
||||
resLen = encodebase64(&resBytes, srcBytes, length, options);
|
||||
return AUTORELEASE([[NSData alloc] initWithBytesNoCopy: resBytes length: resLen freeWhenDone: YES]);
|
||||
}
|
||||
|
||||
- (NSString *)base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)options
|
||||
{
|
||||
void *srcBytes = (void*)[self bytes];
|
||||
NSUInteger length = [self length];
|
||||
NSUInteger resLen;
|
||||
unsigned char *resBytes;
|
||||
|
||||
resLen = encodebase64(&resBytes, srcBytes, length, options);
|
||||
return AUTORELEASE([[NSString alloc] initWithBytesNoCopy: resBytes length: resLen encoding: NSASCIIStringEncoding freeWhenDone: YES]);
|
||||
}
|
||||
|
||||
|
||||
- (NSUInteger) hash
|
||||
{
|
||||
unsigned char buf[64];
|
||||
|
|
|
@ -7,6 +7,9 @@ int main()
|
|||
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
||||
NSData *data;
|
||||
NSData *ref;
|
||||
NSString *str1;
|
||||
NSString *str2;
|
||||
NSString *strEnc;
|
||||
|
||||
PASS_EXCEPTION([[NSData alloc] initWithBase64EncodedString: nil options: 0],
|
||||
NSInvalidArgumentException, "nil argument causes exception");
|
||||
|
@ -73,6 +76,50 @@ int main()
|
|||
PASS_EQUAL(data, ref, "base64 decoding vector 8")
|
||||
[data release];
|
||||
|
||||
str1 = @"In principio creavit Deus caelum et terram.\nTerra autem erat inanis et vacua, et tenebrae super faciem abyssi, et spiritus Dei ferebatur super aquas.\nDixitque Deus: \"Fiat lux\". Et facta est lux.";
|
||||
data = [str1 dataUsingEncoding: NSASCIIStringEncoding];
|
||||
strEnc = [data base64EncodedStringWithOptions:0];
|
||||
data = [[NSData alloc] initWithBase64EncodedString: strEnc options: 0];
|
||||
str2 = [[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding];
|
||||
PASS_EQUAL(str1, str2, "Encode / Decode no lines")
|
||||
[str2 release];
|
||||
|
||||
str1 = @"In principio creavit Deus caelum et terram.\nTerra autem erat inanis et vacua, et tenebrae super faciem abyssi, et spiritus Dei ferebatur super aquas.\nDixitque Deus: \"Fiat lux\". Et facta est lux.";
|
||||
data = [str1 dataUsingEncoding: NSASCIIStringEncoding];
|
||||
strEnc = [data base64EncodedStringWithOptions: (NSDataBase64Encoding64CharacterLineLength | NSDataBase64EncodingEndLineWithLineFeed)];
|
||||
data = [[NSData alloc] initWithBase64EncodedString: strEnc
|
||||
options: NSDataBase64DecodingIgnoreUnknownCharacters];
|
||||
str2 = [[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding];
|
||||
PASS_EQUAL(str1, str2, "Encode / Decode 64 - LF")
|
||||
[str2 release];
|
||||
|
||||
str1 = @"In principio creavit Deus caelum et terram.\nTerra autem erat inanis et vacua, et tenebrae super faciem abyssi, et spiritus Dei ferebatur super aquas.\nDixitque Deus: \"Fiat lux\". Et facta est lux.";
|
||||
data = [str1 dataUsingEncoding: NSASCIIStringEncoding];
|
||||
strEnc = [data base64EncodedStringWithOptions: (NSDataBase64Encoding76CharacterLineLength | NSDataBase64EncodingEndLineWithLineFeed)];
|
||||
data = [[NSData alloc] initWithBase64EncodedString: strEnc
|
||||
options: NSDataBase64DecodingIgnoreUnknownCharacters];
|
||||
str2 = [[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding];
|
||||
PASS_EQUAL(str1, str2, "Encode / Decode 76 - LF")
|
||||
[str2 release];
|
||||
|
||||
str1 = @"In principio creavit Deus caelum et terram.\nTerra autem erat inanis et vacua, et tenebrae super faciem abyssi, et spiritus Dei ferebatur super aquas.\nDixitque Deus: \"Fiat lux\". Et facta est lux.";
|
||||
data = [str1 dataUsingEncoding: NSASCIIStringEncoding];
|
||||
strEnc = [data base64EncodedStringWithOptions: (NSDataBase64Encoding64CharacterLineLength | NSDataBase64EncodingEndLineWithCarriageReturn)];
|
||||
data = [[NSData alloc] initWithBase64EncodedString: strEnc
|
||||
options: NSDataBase64DecodingIgnoreUnknownCharacters];
|
||||
str2 = [[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding];
|
||||
PASS_EQUAL(str1, str2, "Encode / Decode 64 - CR")
|
||||
[str2 release];
|
||||
|
||||
str1 = @"In principio creavit Deus caelum et terram.\nTerra autem erat inanis et vacua, et tenebrae super faciem abyssi, et spiritus Dei ferebatur super aquas.\nDixitque Deus: \"Fiat lux\". Et facta est lux.";
|
||||
data = [str1 dataUsingEncoding: NSASCIIStringEncoding];
|
||||
strEnc = [data base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];
|
||||
data = [[NSData alloc] initWithBase64EncodedString: strEnc
|
||||
options: NSDataBase64DecodingIgnoreUnknownCharacters];
|
||||
str2 = [[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding];
|
||||
PASS_EQUAL(str1, str2, "Encode / Decode 64 - implicit CR LF")
|
||||
[str2 release];
|
||||
|
||||
[arp release]; arp = nil;
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue