File: XADStringICU.m

package info (click to toggle)
unar 1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 6,664 kB
  • sloc: ansic: 52,939; objc: 39,563; cpp: 4,074; makefile: 99; perl: 10
file content (130 lines) | stat: -rw-r--r-- 3,415 bytes parent folder | download | duplicates (5)
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