mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
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:
parent
39fb5269ff
commit
c5dc2d494d
3 changed files with 119 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
|
||||
|
|
|
@ -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;
|
||||
|
|
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];
|
||||
|
|
Loading…
Reference in a new issue