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 131
|
/*
* This implementation does not really work much at all, because iconv is horrible. Use ICU instead.
*/
#import "XADString.h"
#import <iconv.h>
#define MaxEncodingNameLength 128
static void IconvNameForEncodingName(char *cstr,NSString *name);
@implementation XADString (PlatformSpecific)
+(NSString *)stringForData:(NSData *)data encodingName:(NSString *)encoding
{
char encbuf[MaxEncodingNameLength+1];
IconvNameForEncodingName(encbuf,encoding);
iconv_t ic=iconv_open("UCS-2-INTERNAL",encbuf);
if(ic==(iconv_t)(-1)) return nil;
char *inptr=(char *)[data bytes]; // iconv is horrible and doesn't declare its input as const.
size_t inlen=[data length];
uint16_t chars[1024];
NSMutableString *string=[NSMutableString string];
while(inlen)
{
char *outptr=(char *)&chars;
size_t outlen=sizeof(chars)/sizeof(*chars)-1;
if(iconv(ic,&inptr,&inlen,&outptr,&outlen)==-1)
{
if(errno!=E2BIG) return nil;
}
*(uint16_t *)outptr=0;
[string appendFormat:@"%S",chars];
}
return [NSString stringWithString:string];
}
+(NSData *)dataForString:(NSString *)string encodingName:(NSString *)encoding
{
char encbuf[MaxEncodingNameLength+1];
IconvNameForEncodingName(encbuf,encoding);
iconv_t ic=iconv_open(encbuf,"UCS-2-INTERNAL");
if(ic==(iconv_t)(-1)) return nil;
int numchars=[string length];
unichar chars[numchars];
[string getCharacters:chars range:NSMakeRange(0,numchars)];
char *inptr=(char *)chars;
size_t inlen=numchars*2;
char bytes[1024];
NSMutableData *data=[NSMutableData data];
while(inlen)
{
char *outptr=bytes;
size_t outlen=sizeof(bytes);
if(iconv(ic,&inptr,&inlen,&outptr,&outlen)==-1)
{
if(errno!=E2BIG) return nil;
}
[data appendBytes:bytes length:outptr-bytes];
}
return [NSData dataWithData:data];
}
+(NSArray *)availableEncodingNames
{
}
static void IconvNameForEncodingName(char *cstr,NSString *name)
{
static NSDictionary *replacementdictionary=nil;
if(!replacementdictionary) replacementdictionary=[[NSDictionary alloc] initWithObjectsAndKeys:
// Try to map normal names to weird iconv ones. Apparently these vary from implementation
// to implementation though and this will be all wrong anyway. Sheesh.
@"MACCENTRALEUROPE",@"x-mac-centraleurroman",
@"MACICELAND",@"x-mac-icelandic",
@"MACCROATIAN",@"x-mac-croatian",
@"MACROMANIA",@"x-mac-romanian",
@"MACCYRILLIC",@"x-mac-cyrillic",
@"MACUKRAINE",@"x-mac-ukrainian",
@"MACGREEK",@"x-mac-greek",
@"MACTURKISH",@"x-mac-turkish",
@"MACHEBREW",@"x-mac-hebrew",
@"MACARABIC",@"x-mac-arabic",
@"MACTHAI",@"x-mac-thai",
// Still unknown:
//x-mac-japanese
//x-mac-trad-chinese
//x-mac-korean
//x-mac-devanagari
//x-mac-gurmukhi
//x-mac-gujarati
//x-mac-simp-chinese
//x-mac-tibetan
//x-mac-symbol
//x-mac-dingbats
//x-mac-celtic
//x-mac-gaelic
//x-mac-farsi
//x-mac-inuit
//x-mac-roman-latin1
nil];
name=[name lowercaseString];
NSString *replacement=[replacementdictionary objectForKey:name];
if(replacement) name=replacement;
NSAutoreleasePool *pool=[NSAutoreleasePool new];
NSData *data=[name dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
int length=[data length];
if(length>MaxEncodingNameLength) length=MaxEncodingNameLength;
memcpy(cstr,[data bytes],length);
cstr[length]=0;
[pool release];
}
@end
|