123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- #import "NSData+XMPP.h"
- #import <CommonCrypto/CommonDigest.h>
- #if ! __has_feature(objc_arc)
- #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
- #endif
- @implementation NSData (XMPP)
- static char encodingTable[64] = {
- 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
- 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
- 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
- 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' };
- - (NSData *)xmpp_md5Digest
- {
- unsigned char result[CC_MD5_DIGEST_LENGTH];
-
- CC_MD5([self bytes], (CC_LONG)[self length], result);
- return [NSData dataWithBytes:result length:CC_MD5_DIGEST_LENGTH];
- }
- - (NSData *)xmpp_sha1Digest
- {
- unsigned char result[CC_SHA1_DIGEST_LENGTH];
-
- CC_SHA1([self bytes], (CC_LONG)[self length], result);
- return [NSData dataWithBytes:result length:CC_SHA1_DIGEST_LENGTH];
- }
- - (NSString *)xmpp_hexStringValue
- {
- NSMutableString *stringBuffer = [NSMutableString stringWithCapacity:([self length] * 2)];
-
- const unsigned char *dataBuffer = [self bytes];
- int i;
-
- for (i = 0; i < [self length]; ++i)
- {
- [stringBuffer appendFormat:@"%02x", (unsigned int)dataBuffer[i]];
- }
-
- return [stringBuffer copy];
- }
- - (NSString *)xmpp_base64Encoded
- {
- const unsigned char *bytes = [self bytes];
- NSMutableString *result = [NSMutableString stringWithCapacity:[self length]];
- unsigned long ixtext = 0;
- unsigned long lentext = [self length];
- long ctremaining = 0;
- unsigned char inbuf[3], outbuf[4];
- unsigned short i = 0;
- unsigned short charsonline = 0, ctcopy = 0;
- unsigned long ix = 0;
-
- while( YES )
- {
- ctremaining = lentext - ixtext;
- if( ctremaining <= 0 ) break;
-
- for( i = 0; i < 3; i++ ) {
- ix = ixtext + i;
- if( ix < lentext ) inbuf[i] = bytes[ix];
- else inbuf [i] = 0;
- }
-
- outbuf [0] = (inbuf [0] & 0xFC) >> 2;
- outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
- outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
- outbuf [3] = inbuf [2] & 0x3F;
- ctcopy = 4;
-
- switch( ctremaining )
- {
- case 1:
- ctcopy = 2;
- break;
- case 2:
- ctcopy = 3;
- break;
- }
-
- for( i = 0; i < ctcopy; i++ )
- [result appendFormat:@"%c", encodingTable[outbuf[i]]];
-
- for( i = ctcopy; i < 4; i++ )
- [result appendString:@"="];
-
- ixtext += 3;
- charsonline += 4;
- }
-
- return [NSString stringWithString:result];
- }
- - (NSData *)xmpp_base64Decoded
- {
- const unsigned char *bytes = [self bytes];
- NSMutableData *result = [NSMutableData dataWithCapacity:[self length]];
-
- unsigned long ixtext = 0;
- unsigned long lentext = [self length];
- unsigned char ch = 0;
- unsigned char inbuf[4] = {0, 0, 0, 0};
- unsigned char outbuf[3] = {0, 0, 0};
- short i = 0, ixinbuf = 0;
- BOOL flignore = NO;
- BOOL flendtext = NO;
-
- while( YES )
- {
- if( ixtext >= lentext ) break;
- ch = bytes[ixtext++];
- flignore = NO;
-
- if( ( ch >= 'A' ) && ( ch <= 'Z' ) ) ch = ch - 'A';
- else if( ( ch >= 'a' ) && ( ch <= 'z' ) ) ch = ch - 'a' + 26;
- else if( ( ch >= '0' ) && ( ch <= '9' ) ) ch = ch - '0' + 52;
- else if( ch == '+' ) ch = 62;
- else if( ch == '=' ) flendtext = YES;
- else if( ch == '/' ) ch = 63;
- else flignore = YES;
-
- if( ! flignore )
- {
- short ctcharsinbuf = 3;
- BOOL flbreak = NO;
-
- if( flendtext )
- {
- if( ! ixinbuf ) break;
- if( ( ixinbuf == 1 ) || ( ixinbuf == 2 ) ) ctcharsinbuf = 1;
- else ctcharsinbuf = 2;
- ixinbuf = 3;
- flbreak = YES;
- }
-
- inbuf [ixinbuf++] = ch;
-
- if( ixinbuf == 4 )
- {
- ixinbuf = 0;
- outbuf [0] = ( inbuf[0] << 2 ) | ( ( inbuf[1] & 0x30) >> 4 );
- outbuf [1] = ( ( inbuf[1] & 0x0F ) << 4 ) | ( ( inbuf[2] & 0x3C ) >> 2 );
- outbuf [2] = ( ( inbuf[2] & 0x03 ) << 6 ) | ( inbuf[3] & 0x3F );
-
- for( i = 0; i < ctcharsinbuf; i++ )
- [result appendBytes:&outbuf[i] length:1];
- }
-
- if( flbreak ) break;
- }
- }
-
- return [NSData dataWithData:result];
- }
- - (BOOL)xmpp_isJPEG
- {
- if (self.length > 4)
- {
- unsigned char buffer[4];
- [self getBytes:&buffer length:4];
-
- return buffer[0]==0xff &&
- buffer[1]==0xd8 &&
- buffer[2]==0xff &&
- buffer[3]==0xe0;
- }
-
- return NO;
- }
- - (BOOL)xmpp_isPNG
- {
- if (self.length > 4)
- {
- unsigned char buffer[4];
- [self getBytes:&buffer length:4];
-
- return buffer[0]==0x89 &&
- buffer[1]==0x50 &&
- buffer[2]==0x4e &&
- buffer[3]==0x47;
- }
-
- return NO;
- }
- - (NSString *)xmpp_imageType
- {
- NSString *result = nil;
-
- if([self xmpp_isPNG])
- {
- result = @"image/png";
- }
- else if([self xmpp_isJPEG])
- {
- result = @"image/jpeg";
- }
-
- return result;
- }
- @end
- #ifndef XMPP_EXCLUDE_DEPRECATED
- @implementation NSData (XMPPDeprecated)
- - (NSData *)md5Digest {
- return [self xmpp_md5Digest];
- }
- - (NSData *)sha1Digest {
- return [self xmpp_sha1Digest];
- }
- - (NSString *)hexStringValue {
- return [self xmpp_hexStringValue];
- }
- - (NSString *)base64Encoded {
- return [self xmpp_base64Encoded];
- }
- - (NSData *)base64Decoded {
- return [self xmpp_base64Decoded];
- }
- @end
- #endif
|