NSMutableString deleteCharactersInRange: implementation + tests

Change-Id: I711a6ba7518f1dc323c3df436c5b0aede3c50353
This commit is contained in:
ciciplusplus
2026-01-13 23:13:29 +01:00
parent f1ce8bb100
commit 230bc855fc
4 changed files with 72 additions and 8 deletions

View File

@@ -75,7 +75,7 @@ jobs:
CMAKE: ${{ github.workspace }}/vendor/cmake/bin/cmake
# This step ensures that our non-iOS-specific tests are passing on macOS itself!
- name: Sanity check tests
run: cc tests/TestApp_source/cli_tests.m tests/TestApp_source/CGAffineTransform.c tests/TestApp_source/SyncTester.m -framework CoreFoundation -framework CoreGraphics -DDEFINE_ME_WHEN_BUILDING_ON_MACOS -DTestApp_cli_tests_main=main -ObjC && ./a.out
run: cc tests/TestApp_source/cli_tests.m tests/TestApp_source/CGAffineTransform.c tests/TestApp_source/SyncTester.m -framework CoreFoundation -framework Foundation -framework CoreGraphics -DDEFINE_ME_WHEN_BUILDING_ON_MACOS -DTestApp_cli_tests_main=main -ObjC && ./a.out
- name: Build
run: cargo build --target x86_64-apple-darwin --release
env:

View File

@@ -1234,15 +1234,33 @@ pub const CLASSES: ClassExports = objc_classes! {
}
- (())deleteCharactersInRange:(NSRange)range {
// Below implementation handles a trivial case -
// whole string is deleted!
let location = range.location;
assert_eq!(location, 0); // TODO
let len: NSUInteger = msg![env; this length];
let length = range.length;
assert_eq!(len, length); // TODO
let empty = get_static_str(env, "");
() = msg![env; this setString:empty];
let left: id = if location == 0 {
get_static_str(env, "")
} else {
let left_range = NSRange {
location: 0,
length: location,
};
msg![env; this substringWithRange:left_range]
};
let idx_after_removal = location + length;
let lenght_str: NSUInteger = msg![env; this length];
let right: id = if idx_after_removal == lenght_str {
get_static_str(env, "")
} else {
let right_range = NSRange {
location: idx_after_removal,
length: lenght_str - idx_after_removal,
};
msg![env; this substringWithRange:right_range]
};
let res: id = msg![env; left stringByAppendingString:right];
() = msg![env; this setString:res];
}
@end
@@ -1532,6 +1550,18 @@ pub const CLASSES: ClassExports = objc_classes! {
*env.objc.borrow_mut(this) = host_object;
}
- (id)substringWithRange:(NSRange)range {
let host_object = env.objc.borrow_mut::<StringHostObject>(this);
let (orig_string, did_convert) = host_object.convert_to_utf16_inplace();
if did_convert {
log_dbg!("[{:?} substringWithRange]: converted string to UTF-16", this);
}
let host_string =
orig_string[(range.location as usize)..((range.location + range.length) as usize)].to_vec();
let res = from_u16_vec(env, host_string);
autorelease(env, res)
}
@end
};

View File

@@ -3070,6 +3070,31 @@ int test_CFURLHasDirectoryPath() {
return 0;
}
int test_NSMutableString_deleteCharactersInRange() {
NSMutableString *str = [NSMutableString stringWithUTF8String:"abc"];
NSRange r1 = {0, 3};
[str deleteCharactersInRange:r1];
NSString *expected = [NSString stringWithUTF8String:""];
if (!CFEqual(str, expected)) {
return -1;
}
str = [NSMutableString stringWithUTF8String:"abc"];
NSRange r2 = {1, 1};
[str deleteCharactersInRange:r2];
expected = [NSString stringWithUTF8String:"ac"];
if (!CFEqual(str, expected)) {
return -2;
}
str = [NSMutableString stringWithUTF8String:"abc"];
NSRange r3 = {0, 2};
[str deleteCharactersInRange:r3];
expected = [NSString stringWithUTF8String:"c"];
if (!CFEqual(str, expected)) {
return -3;
}
return 0;
}
// clang-format off
#define FUNC_DEF(func) \
{ &func, #func }
@@ -3136,6 +3161,7 @@ struct {
FUNC_DEF(test_CGGeometry),
FUNC_DEF(test_CFURLHasDirectoryPath),
FUNC_DEF(test_CGImage_JPEG),
FUNC_DEF(test_NSMutableString_deleteCharactersInRange),
};
// clang-format on

View File

@@ -24,6 +24,11 @@ typedef signed char BOOL;
typedef unsigned long NSUInteger;
typedef signed long NSInteger;
typedef struct _NSRange {
NSUInteger location;
NSUInteger length;
} NSRange;
#define nil ((id)0)
// id objc_msgSend(id, SEL, ...);
@@ -65,6 +70,9 @@ typedef signed long NSInteger;
+ (instancetype)stringWithFormat:(NSString *)format, ...;
+ (instancetype)stringWithUTF8String:(const char *)string;
@end
@interface NSMutableString : NSString
- (void)deleteCharactersInRange:(NSRange)range;
@end
@interface NSValue : NSObject
@end