XADMaster/XADStringICU.m
2018-03-21 14:24:50 +02:00

150 lines
4.2 KiB
Objective-C

/*
* XADStringICU.m
*
* Copyright (c) 2017-present, MacPaw Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#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