1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
#import "XADString.h"
#import <unicode/ucnv.h>
@implementation XADString (PlatformSpecific)
+(BOOL)canDecodeData:(NSData *)data encodingName:(NSString *)encoding
{
return [self canDecodeBytes:[data bytes] length:[data length] encodingName:encoding];
}
+(BOOL)canDecodeBytes:(const void *)bytes length:(size_t)length encodingName:(NSString *)encoding
{
if(length==0) return YES;
UErrorCode err=U_ZERO_ERROR;
UConverter *conv=ucnv_open([encoding UTF8String],&err);
if(!conv) return NO;
ucnv_setToUCallBack(conv,UCNV_TO_U_CALLBACK_STOP,NULL,NULL,NULL,&err);
if(U_FAILURE(err)) { ucnv_close(conv); return NO; }
int numchars=ucnv_toUChars(conv,NULL,0,bytes,length,&err);
ucnv_close(conv);
return err==U_BUFFER_OVERFLOW_ERROR;
}
+(NSString *)stringForData:(NSData *)data encodingName:(NSString *)encoding
{
return [self stringForBytes:[data bytes] length:[data length] encodingName:encoding];
}
+(NSString *)stringForBytes:(const void *)bytes length:(size_t)length encodingName:(NSString *)encoding;
{
if(length==0) return @"";
UErrorCode err=U_ZERO_ERROR;
UConverter *conv=ucnv_open([encoding UTF8String],&err);
if(!conv) return nil;
ucnv_setToUCallBack(conv,UCNV_TO_U_CALLBACK_STOP,NULL,NULL,NULL,&err);
if(U_FAILURE(err)) { ucnv_close(conv); return nil; }
int numchars=ucnv_toUChars(conv,NULL,0,bytes,length,&err);
if(err!=U_BUFFER_OVERFLOW_ERROR) { ucnv_close(conv); return nil; }
err=U_ZERO_ERROR;
unichar *charbuf=malloc(numchars*sizeof(unichar));
ucnv_toUChars(conv,charbuf,numchars,bytes,length,&err);
ucnv_close(conv);
if(U_FAILURE(err))
{
free(charbuf);
return nil;
}
else
{
return [[[NSString alloc] initWithCharactersNoCopy:charbuf length:numchars freeWhenDone:YES] autorelease];
}
}
+(NSData *)dataForString:(NSString *)string encodingName:(NSString *)encoding
{
if([string length]==0) return [NSData data];
UErrorCode err=U_ZERO_ERROR;
UConverter *conv=ucnv_open([encoding UTF8String],&err);
if(!conv) return nil;
ucnv_setFromUCallBack(conv,UCNV_FROM_U_CALLBACK_STOP,NULL,NULL,NULL,&err);
if(U_FAILURE(err)) { ucnv_close(conv); return nil; }
int numchars=[string length];
unichar charbuf[numchars];
[string getCharacters:charbuf range:NSMakeRange(0,numchars)];
int numbytes=ucnv_fromUChars(conv,NULL,0,charbuf,numchars,&err);
if(err!=U_BUFFER_OVERFLOW_ERROR) { ucnv_close(conv); return nil; }
err=U_ZERO_ERROR;
char *bytebuf=malloc(numbytes);
ucnv_fromUChars(conv,bytebuf,numbytes,charbuf,numchars,&err);
ucnv_close(conv);
if(U_FAILURE(err))
{
free(bytebuf);
return nil;
}
else
{
return [NSData dataWithBytesNoCopy:bytebuf length:numbytes freeWhenDone:YES];
}
}
+(NSArray *)availableEncodingNames
{
int numencodings=ucnv_countAvailable();
NSMutableArray *array=[NSMutableArray arrayWithCapacity:numencodings];
UErrorCode err=U_ZERO_ERROR;
for(int i=0;i<numencodings;i++)
{
const char *name=ucnv_getAvailableName(i);
NSMutableArray *encodingarray=[NSMutableArray arrayWithObject:@""];
err=U_ZERO_ERROR;
UEnumeration *enumeration=ucnv_openStandardNames(name,"IANA",&err);
const char *alias;
while(alias=uenum_next(enumeration,NULL,&err))
{
[encodingarray addObject:[NSString stringWithUTF8String:alias]];
}
uenum_close(enumeration);
if([encodingarray count]==1) [encodingarray addObject:[NSString stringWithUTF8String:name]];
[array addObject:encodingarray];
}
return array;
}
@end
|