[Substrate-commits] SF.net SVN: substrate: [269] trunk
Brought to you by:
landonf
|
From: <la...@us...> - 2006-08-31 02:09:20
|
Revision: 269
http://svn.sourceforge.net/substrate/?rev=269&view=rev
Author: landonf
Date: 2006-08-30 19:09:09 -0700 (Wed, 30 Aug 2006)
Log Message:
-----------
Add support for lossy and non-lossy conversions
Modified Paths:
--------------
trunk/Foundation/NSUnicodeString.h
trunk/Foundation/NSUnicodeString.m
trunk/Tests/NSUnicodeString.m
Modified: trunk/Foundation/NSUnicodeString.h
===================================================================
--- trunk/Foundation/NSUnicodeString.h 2006-08-31 00:02:26 UTC (rev 268)
+++ trunk/Foundation/NSUnicodeString.h 2006-08-31 02:09:09 UTC (rev 269)
@@ -33,8 +33,10 @@
*/
#include <Foundation/NSString.h>
+
+#include <unicode/ucnv.h>
+#include <unicode/ucnv_err.h>
#include <unicode/ustring.h>
-#include <unicode/ucnv.h>
/*!
* @ingroup NSUnicodeString
Modified: trunk/Foundation/NSUnicodeString.m
===================================================================
--- trunk/Foundation/NSUnicodeString.m 2006-08-31 00:02:26 UTC (rev 268)
+++ trunk/Foundation/NSUnicodeString.m 2006-08-31 02:09:09 UTC (rev 269)
@@ -228,6 +228,17 @@
return nil;
}
+ /* Skip bad code points. This *seems* to be what Apple does,
+ * but I could be wrong */
+ ucnv_setFromUCallBack(conv, UCNV_FROM_U_CALLBACK_SKIP, NULL, NULL, NULL, &err);
+
+ /* Did ucnv_setFromUCallback() fail? */
+ if (U_FAILURE(err)) {
+ [NSException raise: NSInternalInconsistencyException format: @"Failure in IBM ICU's ucnv_setFromUCallback()"];
+ ucnv_close(conv);
+ return nil;
+ }
+
/* Do the conversion */
_string = NSZoneMalloc(NULL, allocSize);
while (1) {
@@ -250,7 +261,7 @@
_string = NSZoneRealloc(NULL, _string, allocSize);
continue;
} else {
- [NSException raise: NSInternalInconsistencyException format: @"Failure in IBM ICU's ucnv_toUChars()"];
+ [NSException raise: NSCharacterConversionException format: @"Failure in IBM ICU's ucnv_toUChars()"];
NSZoneFree(NULL, _string);
ucnv_close(conv);
[self release];
@@ -475,10 +486,22 @@
/* Did ucnv_open() fail? */
if (U_FAILURE(err)) {
[NSException raise: NSInternalInconsistencyException format: @"Failure in IBM ICU's ucnv_open()"];
- [self release];
return nil;
}
+ /* Set up lossy character handling */
+ if (lossy)
+ ucnv_setFromUCallBack(conv, UCNV_FROM_U_CALLBACK_SKIP, NULL, NULL, NULL, &err);
+ else
+ ucnv_setFromUCallBack(conv, UCNV_FROM_U_CALLBACK_STOP, NULL, NULL, NULL, &err);
+
+ /* Did ucnv_setFromUCallback() fail? */
+ if (U_FAILURE(err)) {
+ [NSException raise: NSInternalInconsistencyException format: @"Failure in IBM ICU's ucnv_setFromUCallback()"];
+ ucnv_close(conv);
+ return nil;
+ }
+
/* Do the conversion */
bytes = NSZoneMalloc(NULL, allocSize);
while (1) {
@@ -499,11 +522,16 @@
allocSize = newAllocSize;
bytes = NSZoneRealloc(NULL, bytes, allocSize);
continue;
+ } else if (err == U_ILLEGAL_CHAR_FOUND) {
+ /* Invalid character sequence found for the given
+ * destination encoding scheme */
+ NSZoneFree(NULL, bytes);
+ ucnv_close(conv);
+ return nil;
} else {
[NSException raise: NSInternalInconsistencyException format: @"Failure in IBM ICU's ucnv_toUChars()"];
NSZoneFree(NULL, bytes);
ucnv_close(conv);
- [self release];
return nil;
}
}
@@ -511,8 +539,6 @@
/* Success. Let's shove it into an NSData instance */
return [NSData dataWithBytesNoCopy: bytes length: allocSize freeWhenDone: YES];
}
-
-
/*! @} */
Modified: trunk/Tests/NSUnicodeString.m
===================================================================
--- trunk/Tests/NSUnicodeString.m 2006-08-31 00:02:26 UTC (rev 268)
+++ trunk/Tests/NSUnicodeString.m 2006-08-31 02:09:09 UTC (rev 269)
@@ -33,8 +33,21 @@
#include <Foundation/NSAutoreleasePool.h>
#include <string.h>
+#include <stdlib.h>
/*
+ * Test setup/teardown
+ */
+static NSAutoreleasePool *releasePool;
+static void setUp(void) {
+ releasePool = [[NSAutoreleasePool alloc] init];
+}
+
+static void tearDown(void) {
+ [releasePool release];
+}
+
+/*
* Test data for all supported encodings
*/
@@ -164,7 +177,6 @@
#define ENCODING_INIT_TEST(stringEncoding) \
START_TEST(test_ ## stringEncoding) { \
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; \
NSString *string; \
NSData *data; \
string = [[NSString alloc] initWithBytes: stringEncoding ## _data length: sizeof(stringEncoding ## _data) encoding: stringEncoding]; \
@@ -172,7 +184,6 @@
data = [string dataUsingEncoding: stringEncoding allowLossyConversion: NO]; \
fail_if(data == nil, "-[NSString dataUsingEncoding: allowLossyConversion:] return nil for NSStringEncoding %d.", stringEncoding); \
fail_unless(memcmp([data bytes], stringEncoding ## _data, sizeof(stringEncoding ## _data)) == 0, "-[NSString dataUsingEncoding: allowLossyConversion:] return data that does not match the original for NSStringEncoding %d.", stringEncoding); \
- [pool release]; \
[string release]; \
} \
END_TEST
@@ -223,10 +234,26 @@
}
END_TEST
+START_TEST (test_dataUsingEncodingStringEncodingAllowLossyConversion) {
+ NSString *string;
+ NSData *data;
+
+ /* Try lossy and non-lossy conversion from EUC to ASCII */
+ string = [[NSString alloc] initWithBytes: NSJapaneseEUCStringEncoding_data length: sizeof(NSJapaneseEUCStringEncoding_data) encoding: NSJapaneseEUCStringEncoding];
+ data = [string dataUsingEncoding: NSASCIIStringEncoding allowLossyConversion: YES];
+ fail_if(data == nil, "-[NSString dataUsingEncoding: NSASCIIStringEncoding allowLossyConversion: YES] returned nil.");
+
+
+ data = [string dataUsingEncoding: NSASCIIStringEncoding allowLossyConversion: NO];
+ fail_unless(data == nil, "-[NSString dataUsingEncoding: NSASCIIStringEncoding allowLossyConversion: NO] did not return nil with lossy data.");
+}
+END_TEST
+
Suite *NSUnicodeString_suite(void) {
Suite *s = suite_create("NSUnicodeString");
TCase *tc_init = tcase_create("Initialization");
+ tcase_add_checked_fixture(tc_init, setUp, tearDown);
suite_add_tcase(s, tc_init);
tcase_add_test(tc_init, test_NSASCIIStringEncoding);
tcase_add_test(tc_init, test_NSJapaneseEUCStringEncoding);
@@ -245,5 +272,10 @@
tcase_add_test(tc_init, test_NSMacOSRomanStringEncoding);
tcase_add_test(tc_init, test_initWithBytesNoCopyLengthEncodingFreeWhenDone);
+ TCase *tc_conv = tcase_create("Conversion");
+ tcase_add_checked_fixture(tc_conv, setUp, tearDown);
+ suite_add_tcase(s, tc_conv);
+ tcase_add_test(tc_conv, test_dataUsingEncodingStringEncodingAllowLossyConversion);
+
return (s);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|