base64EncodedDataWithOptions, base64EncodedStringWithOptions: first implementation

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@38634 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Riccardo Mottola 2015-06-14 16:17:17 +00:00
parent 39fb5269ff
commit c5dc2d494d
3 changed files with 119 additions and 2 deletions

View file

@ -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

View file

@ -121,6 +121,12 @@ enum {
range: (NSRange)aRange;
- (NSData*) subdataWithRange: (NSRange)aRange;
// base64
#if OS_API_VERSION(MAC_OS_X_VERSION_10_9,GS_API_LATEST)
- (NSData *)base64EncodedDataWithOptions:(NSDataBase64EncodingOptions)options;
- (NSString *)base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)options;
#endif
// Querying a Data Object
- (BOOL) isEqualToData: (NSData*)other;

View file

@ -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];