diff --git a/packages/data_detector/.gitignore b/packages/data_detector/.gitignore new file mode 100644 index 00000000..ac5aa989 --- /dev/null +++ b/packages/data_detector/.gitignore @@ -0,0 +1,29 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +build/ diff --git a/packages/data_detector/.metadata b/packages/data_detector/.metadata new file mode 100644 index 00000000..a91c48e9 --- /dev/null +++ b/packages/data_detector/.metadata @@ -0,0 +1,27 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819" + channel: "stable" + +project_type: plugin_ffi + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/packages/data_detector/CHANGELOG.md b/packages/data_detector/CHANGELOG.md new file mode 100644 index 00000000..41cc7d81 --- /dev/null +++ b/packages/data_detector/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/packages/data_detector/LICENSE b/packages/data_detector/LICENSE new file mode 100644 index 00000000..ba75c69f --- /dev/null +++ b/packages/data_detector/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/packages/data_detector/README.md b/packages/data_detector/README.md new file mode 100644 index 00000000..cd727b9b --- /dev/null +++ b/packages/data_detector/README.md @@ -0,0 +1,95 @@ +# data_detector + +A new Flutter FFI plugin project. + +## Getting Started + +This project is a starting point for a Flutter +[FFI plugin](https://flutter.dev/to/ffi-package), +a specialized package that includes native code directly invoked with Dart FFI. + +## Project structure + +This template uses the following structure: + +* `src`: Contains the native source code, and a CmakeFile.txt file for building + that source code into a dynamic library. + +* `lib`: Contains the Dart code that defines the API of the plugin, and which + calls into the native code using `dart:ffi`. + +* platform folders (`android`, `ios`, `windows`, etc.): Contains the build files + for building and bundling the native code library with the platform application. + +## Building and bundling native code + +The `pubspec.yaml` specifies FFI plugins as follows: + +```yaml + plugin: + platforms: + some_platform: + ffiPlugin: true +``` + +This configuration invokes the native build for the various target platforms +and bundles the binaries in Flutter applications using these FFI plugins. + +This can be combined with dartPluginClass, such as when FFI is used for the +implementation of one platform in a federated plugin: + +```yaml + plugin: + implements: some_other_plugin + platforms: + some_platform: + dartPluginClass: SomeClass + ffiPlugin: true +``` + +A plugin can have both FFI and method channels: + +```yaml + plugin: + platforms: + some_platform: + pluginClass: SomeName + ffiPlugin: true +``` + +The native build systems that are invoked by FFI (and method channel) plugins are: + +* For Android: Gradle, which invokes the Android NDK for native builds. + * See the documentation in android/build.gradle. +* For iOS and MacOS: Xcode, via CocoaPods. + * See the documentation in ios/data_detector.podspec. + * See the documentation in macos/data_detector.podspec. +* For Linux and Windows: CMake. + * See the documentation in linux/CMakeLists.txt. + * See the documentation in windows/CMakeLists.txt. + +## Binding to native code + +To use the native code, bindings in Dart are needed. +To avoid writing these by hand, they are generated from the header file +(`src/data_detector.h`) by `package:ffigen`. +Regenerate the bindings by running `dart run ffigen --config ffigen.yaml`. + +## Invoking native code + +Very short-running native functions can be directly invoked from any isolate. +For example, see `sum` in `lib/data_detector.dart`. + +Longer-running functions should be invoked on a helper isolate to avoid +dropping frames in Flutter applications. +For example, see `sumAsync` in `lib/data_detector.dart`. + +## Flutter help + +For help getting started with Flutter, view our +[online documentation](https://docs.flutter.dev), which offers tutorials, +samples, guidance on mobile development, and a full API reference. + +The plugin project was generated without specifying the `--platforms` flag, so no platforms are currently supported. +To add platforms, run `flutter create -t plugin_ffi --platforms .` in this directory. +You can also find a detailed instruction on how to add platforms in the `pubspec.yaml` at https://flutter.dev/to/pubspec-plugin-platforms. diff --git a/packages/data_detector/analysis_options.yaml b/packages/data_detector/analysis_options.yaml new file mode 100644 index 00000000..a5744c1c --- /dev/null +++ b/packages/data_detector/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/packages/data_detector/ffigen.yaml b/packages/data_detector/ffigen.yaml new file mode 100644 index 00000000..251b0be2 --- /dev/null +++ b/packages/data_detector/ffigen.yaml @@ -0,0 +1,28 @@ +# Run with `dart run ffigen --config ffigen.yaml`. +name: DataDetectorBindings +description: | + Bindings for NSDataDetector. + + Regenerate bindings with `dart run ffigen --config ffigen.yaml`. +output: 'lib/src/data_detector_bindings_generated.dart' +language: objc +exclude-all-by-default: true +objc-interfaces: + include: + - 'NSRegularExpression' + - 'NSDataDetector' +structs: + include: + - _NSRange + rename: + _NSRange: NSRange +headers: + entry-points: + - '/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSRegularExpression.h' +preamble: | + // ignore_for_file: always_specify_types + // ignore_for_file: camel_case_types + // ignore_for_file: non_constant_identifier_names +comments: + style: any + length: full diff --git a/packages/data_detector/lib/data_detector.dart b/packages/data_detector/lib/data_detector.dart new file mode 100644 index 00000000..d6ad4543 --- /dev/null +++ b/packages/data_detector/lib/data_detector.dart @@ -0,0 +1,94 @@ +import 'dart:ffi'; +import 'dart:ui'; + +import 'package:ffi/ffi.dart'; +import 'package:objective_c/objective_c.dart' as objc; + +import 'src/data_detector_bindings_generated.dart' as binding; + +export 'src/data_detector_bindings_generated.dart' + show NSTextCheckingType, NSMatchingOptions; + +extension on TextRange { + Pointer toNSRange() { + final range = malloc.allocate(sizeOf()); + range.ref.location = start; + range.ref.length = end - start; + return range; + } +} + +class TextCheckingResult { + TextCheckingResult._(this._inner); + + final binding.NSTextCheckingResult _inner; + + binding.NSTextCheckingType get type => _inner.resultType; + + TextRange get range { + final p = malloc.allocate(sizeOf()); + _inner.getRange(p); + final textRange = + TextRange(start: p.ref.location, end: p.ref.location + p.ref.length); + malloc.free(p); + return textRange; + } + + DateTime? get date { + final timestamp = _inner.date?.timeIntervalSince1970; + if (timestamp == null) { + return null; + } + return DateTime.fromMicrosecondsSinceEpoch((timestamp * 1e6) as int); + } + + Duration get duration => + Duration(microseconds: (_inner.duration * 1e6) as int); + + Uri? get url { + final url = _inner.URL?.absoluteString; + if (url == null) { + return null; + } + return Uri.parse(url.toString()); + } +} + +class DataDetector { + factory DataDetector(binding.NSTextCheckingType type) { + final error = malloc + .allocate>(sizeOf>()); + final detector = + binding.NSDataDetector.alloc().initWithTypes_error_(type.value, error); + if (error.value != nullptr) { + final err = objc.NSError.castFromPointer(error.value); + throw err; + } + return DataDetector._(detector!); + } + + DataDetector._(this._detector); + + final binding.NSDataDetector _detector; + + List matchesInString( + String str, { + binding.NSMatchingOptions? options, + TextRange? range, + }) { + final nsRange = (range ?? TextRange(start: 0, end: str.length)).toNSRange(); + final array = _detector.matchesInString_options_range_( + str.toNSString(), + options ?? binding.NSMatchingOptions.NSMatchingReportCompletion, + nsRange.ref); + malloc.free(nsRange); + + final results = []; + for (var i = 0; i < array.count; i++) { + final result = + binding.NSTextCheckingResult.castFrom(array.objectAtIndex_(i)); + results.add(TextCheckingResult._(result)); + } + return results; + } +} diff --git a/packages/data_detector/lib/src/data_detector_bindings_generated.dart b/packages/data_detector/lib/src/data_detector_bindings_generated.dart new file mode 100644 index 00000000..9d2a7619 --- /dev/null +++ b/packages/data_detector/lib/src/data_detector_bindings_generated.dart @@ -0,0 +1,1750 @@ +// ignore_for_file: always_specify_types +// ignore_for_file: camel_case_types +// ignore_for_file: non_constant_identifier_names + +// AUTO GENERATED FILE, DO NOT EDIT. +// +// Generated by `package:ffigen`. +// ignore_for_file: type=lint +import 'dart:ffi' as ffi; +import 'package:objective_c/objective_c.dart' as objc; + +@ffi.Native Function(ffi.Pointer)>( + isLeaf: true) +external ffi.Pointer + wrapListenerBlock_ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool( + ffi.Pointer block, +); + +final class NSRange extends ffi.Struct { + @ffi.UnsignedLong() + external int location; + + @ffi.UnsignedLong() + external int length; +} + +/// NSTextCheckingResult +class NSTextCheckingResult extends objc.NSObject { + NSTextCheckingResult._(ffi.Pointer pointer, + {bool retain = false, bool release = false}) + : super.castFromPointer(pointer, retain: retain, release: release); + + /// Constructs a [NSTextCheckingResult] that points to the same underlying object as [other]. + NSTextCheckingResult.castFrom(objc.ObjCObjectBase other) + : this._(other.pointer, retain: true, release: true); + + /// Constructs a [NSTextCheckingResult] that wraps the given raw object pointer. + NSTextCheckingResult.castFromPointer(ffi.Pointer other, + {bool retain = false, bool release = false}) + : this._(other, retain: retain, release: release); + + /// Returns whether [obj] is an instance of [NSTextCheckingResult]. + static bool isInstance(objc.ObjCObjectBase obj) { + return _objc_msgSend_0( + obj.pointer, _sel_isKindOfClass_, _class_NSTextCheckingResult); + } + + /// resultType + NSTextCheckingType get resultType { + final _ret = _objc_msgSend_1(this.pointer, _sel_resultType); + return NSTextCheckingType.fromValue(_ret); + } + + /// range + void getRange(ffi.Pointer stret) { + objc.useMsgSendVariants + ? _objc_msgSend_2Stret(stret, this.pointer, _sel_range) + : stret.ref = _objc_msgSend_2(this.pointer, _sel_range); + } + + /// orthography + NSOrthography? get orthography { + final _ret = _objc_msgSend_3(this.pointer, _sel_orthography); + return _ret.address == 0 + ? null + : NSOrthography.castFromPointer(_ret, retain: true, release: true); + } + + /// grammarDetails + objc.NSArray? get grammarDetails { + final _ret = _objc_msgSend_4(this.pointer, _sel_grammarDetails); + return _ret.address == 0 + ? null + : objc.NSArray.castFromPointer(_ret, retain: true, release: true); + } + + /// date + objc.NSDate? get date { + final _ret = _objc_msgSend_5(this.pointer, _sel_date); + return _ret.address == 0 + ? null + : objc.NSDate.castFromPointer(_ret, retain: true, release: true); + } + + /// timeZone + NSTimeZone? get timeZone { + final _ret = _objc_msgSend_6(this.pointer, _sel_timeZone); + return _ret.address == 0 + ? null + : NSTimeZone.castFromPointer(_ret, retain: true, release: true); + } + + /// duration + double get duration { + return objc.useMsgSendVariants + ? _objc_msgSend_7Fpret(this.pointer, _sel_duration) + : _objc_msgSend_7(this.pointer, _sel_duration); + } + + /// components + objc.NSDictionary? get components { + final _ret = _objc_msgSend_8(this.pointer, _sel_components); + return _ret.address == 0 + ? null + : objc.NSDictionary.castFromPointer(_ret, retain: true, release: true); + } + + /// URL + objc.NSURL? get URL { + final _ret = _objc_msgSend_9(this.pointer, _sel_URL); + return _ret.address == 0 + ? null + : objc.NSURL.castFromPointer(_ret, retain: true, release: true); + } + + /// replacementString + objc.NSString? get replacementString { + final _ret = _objc_msgSend_10(this.pointer, _sel_replacementString); + return _ret.address == 0 + ? null + : objc.NSString.castFromPointer(_ret, retain: true, release: true); + } + + /// alternativeStrings + objc.NSArray? get alternativeStrings { + final _ret = _objc_msgSend_4(this.pointer, _sel_alternativeStrings); + return _ret.address == 0 + ? null + : objc.NSArray.castFromPointer(_ret, retain: true, release: true); + } + + /// regularExpression + NSRegularExpression? get regularExpression { + final _ret = _objc_msgSend_27(this.pointer, _sel_regularExpression); + return _ret.address == 0 + ? null + : NSRegularExpression.castFromPointer(_ret, + retain: true, release: true); + } + + /// phoneNumber + objc.NSString? get phoneNumber { + final _ret = _objc_msgSend_10(this.pointer, _sel_phoneNumber); + return _ret.address == 0 + ? null + : objc.NSString.castFromPointer(_ret, retain: true, release: true); + } + + /// numberOfRanges + int get numberOfRanges { + return _objc_msgSend_15(this.pointer, _sel_numberOfRanges); + } + + /// rangeAtIndex: + void rangeAtIndex_(ffi.Pointer stret, int idx) { + objc.useMsgSendVariants + ? _objc_msgSend_28Stret(stret, this.pointer, _sel_rangeAtIndex_, idx) + : stret.ref = _objc_msgSend_28(this.pointer, _sel_rangeAtIndex_, idx); + } + + /// rangeWithName: + void rangeWithName_(ffi.Pointer stret, objc.NSString name) { + objc.useMsgSendVariants + ? _objc_msgSend_29Stret( + stret, this.pointer, _sel_rangeWithName_, name.pointer) + : stret.ref = + _objc_msgSend_29(this.pointer, _sel_rangeWithName_, name.pointer); + } + + /// resultByAdjustingRangesWithOffset: + NSTextCheckingResult resultByAdjustingRangesWithOffset_(int offset) { + final _ret = _objc_msgSend_30( + this.pointer, _sel_resultByAdjustingRangesWithOffset_, offset); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// addressComponents + objc.NSDictionary? get addressComponents { + final _ret = _objc_msgSend_8(this.pointer, _sel_addressComponents); + return _ret.address == 0 + ? null + : objc.NSDictionary.castFromPointer(_ret, retain: true, release: true); + } + + /// orthographyCheckingResultWithRange:orthography: + static NSTextCheckingResult orthographyCheckingResultWithRange_orthography_( + NSRange range, NSOrthography orthography) { + final _ret = _objc_msgSend_31( + _class_NSTextCheckingResult, + _sel_orthographyCheckingResultWithRange_orthography_, + range, + orthography.pointer); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// spellCheckingResultWithRange: + static NSTextCheckingResult spellCheckingResultWithRange_(NSRange range) { + final _ret = _objc_msgSend_32( + _class_NSTextCheckingResult, _sel_spellCheckingResultWithRange_, range); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// grammarCheckingResultWithRange:details: + static NSTextCheckingResult grammarCheckingResultWithRange_details_( + NSRange range, objc.NSArray details) { + final _ret = _objc_msgSend_33(_class_NSTextCheckingResult, + _sel_grammarCheckingResultWithRange_details_, range, details.pointer); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// dateCheckingResultWithRange:date: + static NSTextCheckingResult dateCheckingResultWithRange_date_( + NSRange range, objc.NSDate date) { + final _ret = _objc_msgSend_34(_class_NSTextCheckingResult, + _sel_dateCheckingResultWithRange_date_, range, date.pointer); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// dateCheckingResultWithRange:date:timeZone:duration: + static NSTextCheckingResult + dateCheckingResultWithRange_date_timeZone_duration_(NSRange range, + objc.NSDate date, NSTimeZone timeZone, double duration) { + final _ret = _objc_msgSend_35( + _class_NSTextCheckingResult, + _sel_dateCheckingResultWithRange_date_timeZone_duration_, + range, + date.pointer, + timeZone.pointer, + duration); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// addressCheckingResultWithRange:components: + static NSTextCheckingResult addressCheckingResultWithRange_components_( + NSRange range, objc.NSDictionary components) { + final _ret = _objc_msgSend_36( + _class_NSTextCheckingResult, + _sel_addressCheckingResultWithRange_components_, + range, + components.pointer); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// linkCheckingResultWithRange:URL: + static NSTextCheckingResult linkCheckingResultWithRange_URL_( + NSRange range, objc.NSURL url) { + final _ret = _objc_msgSend_37(_class_NSTextCheckingResult, + _sel_linkCheckingResultWithRange_URL_, range, url.pointer); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// quoteCheckingResultWithRange:replacementString: + static NSTextCheckingResult quoteCheckingResultWithRange_replacementString_( + NSRange range, objc.NSString replacementString) { + final _ret = _objc_msgSend_38( + _class_NSTextCheckingResult, + _sel_quoteCheckingResultWithRange_replacementString_, + range, + replacementString.pointer); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// dashCheckingResultWithRange:replacementString: + static NSTextCheckingResult dashCheckingResultWithRange_replacementString_( + NSRange range, objc.NSString replacementString) { + final _ret = _objc_msgSend_38( + _class_NSTextCheckingResult, + _sel_dashCheckingResultWithRange_replacementString_, + range, + replacementString.pointer); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// replacementCheckingResultWithRange:replacementString: + static NSTextCheckingResult + replacementCheckingResultWithRange_replacementString_( + NSRange range, objc.NSString replacementString) { + final _ret = _objc_msgSend_38( + _class_NSTextCheckingResult, + _sel_replacementCheckingResultWithRange_replacementString_, + range, + replacementString.pointer); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// correctionCheckingResultWithRange:replacementString: + static NSTextCheckingResult + correctionCheckingResultWithRange_replacementString_( + NSRange range, objc.NSString replacementString) { + final _ret = _objc_msgSend_38( + _class_NSTextCheckingResult, + _sel_correctionCheckingResultWithRange_replacementString_, + range, + replacementString.pointer); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// correctionCheckingResultWithRange:replacementString:alternativeStrings: + static NSTextCheckingResult + correctionCheckingResultWithRange_replacementString_alternativeStrings_( + NSRange range, + objc.NSString replacementString, + objc.NSArray alternativeStrings) { + final _ret = _objc_msgSend_39( + _class_NSTextCheckingResult, + _sel_correctionCheckingResultWithRange_replacementString_alternativeStrings_, + range, + replacementString.pointer, + alternativeStrings.pointer); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// regularExpressionCheckingResultWithRanges:count:regularExpression: + static NSTextCheckingResult + regularExpressionCheckingResultWithRanges_count_regularExpression_( + ffi.Pointer ranges, + int count, + NSRegularExpression regularExpression) { + final _ret = _objc_msgSend_40( + _class_NSTextCheckingResult, + _sel_regularExpressionCheckingResultWithRanges_count_regularExpression_, + ranges, + count, + regularExpression.pointer); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// phoneNumberCheckingResultWithRange:phoneNumber: + static NSTextCheckingResult phoneNumberCheckingResultWithRange_phoneNumber_( + NSRange range, objc.NSString phoneNumber) { + final _ret = _objc_msgSend_38( + _class_NSTextCheckingResult, + _sel_phoneNumberCheckingResultWithRange_phoneNumber_, + range, + phoneNumber.pointer); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// transitInformationCheckingResultWithRange:components: + static NSTextCheckingResult + transitInformationCheckingResultWithRange_components_( + NSRange range, objc.NSDictionary components) { + final _ret = _objc_msgSend_36( + _class_NSTextCheckingResult, + _sel_transitInformationCheckingResultWithRange_components_, + range, + components.pointer); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// init + NSTextCheckingResult init() { + final _ret = _objc_msgSend_25(this.pointer, _sel_init); + return NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// new + static NSTextCheckingResult new1() { + final _ret = _objc_msgSend_25(_class_NSTextCheckingResult, _sel_new); + return NSTextCheckingResult.castFromPointer(_ret, + retain: false, release: true); + } + + /// allocWithZone: + static NSTextCheckingResult allocWithZone_(ffi.Pointer<_NSZone> zone) { + final _ret = _objc_msgSend_26( + _class_NSTextCheckingResult, _sel_allocWithZone_, zone); + return NSTextCheckingResult.castFromPointer(_ret, + retain: false, release: true); + } + + /// alloc + static NSTextCheckingResult alloc() { + final _ret = _objc_msgSend_25(_class_NSTextCheckingResult, _sel_alloc); + return NSTextCheckingResult.castFromPointer(_ret, + retain: false, release: true); + } +} + +late final _class_NSTextCheckingResult = objc.getClass("NSTextCheckingResult"); + +enum NSTextCheckingType { + NSTextCheckingTypeOrthography(1), + NSTextCheckingTypeSpelling(2), + NSTextCheckingTypeGrammar(4), + NSTextCheckingTypeDate(8), + NSTextCheckingTypeAddress(16), + NSTextCheckingTypeLink(32), + NSTextCheckingTypeQuote(64), + NSTextCheckingTypeDash(128), + NSTextCheckingTypeReplacement(256), + NSTextCheckingTypeCorrection(512), + NSTextCheckingTypeRegularExpression(1024), + NSTextCheckingTypePhoneNumber(2048), + NSTextCheckingTypeTransitInformation(4096); + + final int value; + const NSTextCheckingType(this.value); + + static NSTextCheckingType fromValue(int value) => switch (value) { + 1 => NSTextCheckingTypeOrthography, + 2 => NSTextCheckingTypeSpelling, + 4 => NSTextCheckingTypeGrammar, + 8 => NSTextCheckingTypeDate, + 16 => NSTextCheckingTypeAddress, + 32 => NSTextCheckingTypeLink, + 64 => NSTextCheckingTypeQuote, + 128 => NSTextCheckingTypeDash, + 256 => NSTextCheckingTypeReplacement, + 512 => NSTextCheckingTypeCorrection, + 1024 => NSTextCheckingTypeRegularExpression, + 2048 => NSTextCheckingTypePhoneNumber, + 4096 => NSTextCheckingTypeTransitInformation, + _ => + throw ArgumentError("Unknown value for NSTextCheckingType: $value"), + }; +} + +late final _sel_resultType = objc.registerName("resultType"); +final _objc_msgSend_1 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Uint64 Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + int Function( + ffi.Pointer, ffi.Pointer)>(); +late final _sel_range = objc.registerName("range"); +final _objc_msgSend_2 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + NSRange Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + NSRange Function( + ffi.Pointer, ffi.Pointer)>(); +final _objc_msgSend_2Stret = objc.msgSendStretPointer + .cast< + ffi.NativeFunction< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + void Function(ffi.Pointer, ffi.Pointer, + ffi.Pointer)>(); + +/// NSOrthography +class NSOrthography extends objc.ObjCObjectBase { + NSOrthography._(ffi.Pointer pointer, + {bool retain = false, bool release = false}) + : super(pointer, retain: retain, release: release); + + /// Constructs a [NSOrthography] that points to the same underlying object as [other]. + NSOrthography.castFrom(objc.ObjCObjectBase other) + : this._(other.pointer, retain: true, release: true); + + /// Constructs a [NSOrthography] that wraps the given raw object pointer. + NSOrthography.castFromPointer(ffi.Pointer other, + {bool retain = false, bool release = false}) + : this._(other, retain: retain, release: release); + + /// Returns whether [obj] is an instance of [NSOrthography]. + static bool isInstance(objc.ObjCObjectBase obj) { + return _objc_msgSend_0( + obj.pointer, _sel_isKindOfClass_, _class_NSOrthography); + } +} + +late final _class_NSOrthography = objc.getClass("NSOrthography"); +final _objc_msgSend_0 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Bool Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + bool Function(ffi.Pointer, + ffi.Pointer, ffi.Pointer)>(); +late final _sel_isKindOfClass_ = objc.registerName("isKindOfClass:"); +late final _sel_orthography = objc.registerName("orthography"); +final _objc_msgSend_3 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Pointer)>(); +late final _sel_grammarDetails = objc.registerName("grammarDetails"); +final _objc_msgSend_4 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Pointer)>(); +late final _sel_date = objc.registerName("date"); +final _objc_msgSend_5 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Pointer)>(); + +/// NSTimeZone +class NSTimeZone extends objc.ObjCObjectBase { + NSTimeZone._(ffi.Pointer pointer, + {bool retain = false, bool release = false}) + : super(pointer, retain: retain, release: release); + + /// Constructs a [NSTimeZone] that points to the same underlying object as [other]. + NSTimeZone.castFrom(objc.ObjCObjectBase other) + : this._(other.pointer, retain: true, release: true); + + /// Constructs a [NSTimeZone] that wraps the given raw object pointer. + NSTimeZone.castFromPointer(ffi.Pointer other, + {bool retain = false, bool release = false}) + : this._(other, retain: retain, release: release); + + /// Returns whether [obj] is an instance of [NSTimeZone]. + static bool isInstance(objc.ObjCObjectBase obj) { + return _objc_msgSend_0(obj.pointer, _sel_isKindOfClass_, _class_NSTimeZone); + } +} + +late final _class_NSTimeZone = objc.getClass("NSTimeZone"); +late final _sel_timeZone = objc.registerName("timeZone"); +final _objc_msgSend_6 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Pointer)>(); +late final _sel_duration = objc.registerName("duration"); +final _objc_msgSend_7 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Double Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + double Function( + ffi.Pointer, ffi.Pointer)>(); +final _objc_msgSend_7Fpret = objc.msgSendFpretPointer + .cast< + ffi.NativeFunction< + ffi.Double Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + double Function( + ffi.Pointer, ffi.Pointer)>(); +late final _sel_components = objc.registerName("components"); +final _objc_msgSend_8 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Pointer)>(); +late final _sel_URL = objc.registerName("URL"); +final _objc_msgSend_9 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Pointer)>(); +late final _sel_replacementString = objc.registerName("replacementString"); +final _objc_msgSend_10 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Pointer)>(); +late final _sel_alternativeStrings = objc.registerName("alternativeStrings"); + +/// NSRegularExpression +class NSRegularExpression extends objc.NSObject { + NSRegularExpression._(ffi.Pointer pointer, + {bool retain = false, bool release = false}) + : super.castFromPointer(pointer, retain: retain, release: release); + + /// Constructs a [NSRegularExpression] that points to the same underlying object as [other]. + NSRegularExpression.castFrom(objc.ObjCObjectBase other) + : this._(other.pointer, retain: true, release: true); + + /// Constructs a [NSRegularExpression] that wraps the given raw object pointer. + NSRegularExpression.castFromPointer(ffi.Pointer other, + {bool retain = false, bool release = false}) + : this._(other, retain: retain, release: release); + + /// Returns whether [obj] is an instance of [NSRegularExpression]. + static bool isInstance(objc.ObjCObjectBase obj) { + return _objc_msgSend_0( + obj.pointer, _sel_isKindOfClass_, _class_NSRegularExpression); + } + + /// An instance of NSRegularExpression is created from a regular expression pattern and a set of options. If the pattern is invalid, nil will be returned and an NSError will be returned by reference. The pattern syntax currently supported is that specified by ICU. + static NSRegularExpression? regularExpressionWithPattern_options_error_( + objc.NSString pattern, + NSRegularExpressionOptions options, + ffi.Pointer> error) { + final _ret = _objc_msgSend_11( + _class_NSRegularExpression, + _sel_regularExpressionWithPattern_options_error_, + pattern.pointer, + options.value, + error); + return _ret.address == 0 + ? null + : NSRegularExpression.castFromPointer(_ret, + retain: true, release: true); + } + + /// initWithPattern:options:error: + NSRegularExpression? initWithPattern_options_error_( + objc.NSString pattern, + NSRegularExpressionOptions options, + ffi.Pointer> error) { + final _ret = _objc_msgSend_12( + this.pointer, + _sel_initWithPattern_options_error_, + pattern.pointer, + options.value, + error); + return _ret.address == 0 + ? null + : NSRegularExpression.castFromPointer(_ret, + retain: true, release: true); + } + + /// pattern + objc.NSString get pattern { + final _ret = _objc_msgSend_13(this.pointer, _sel_pattern); + return objc.NSString.castFromPointer(_ret, retain: true, release: true); + } + + /// options + NSRegularExpressionOptions get options { + final _ret = _objc_msgSend_14(this.pointer, _sel_options); + return NSRegularExpressionOptions.fromValue(_ret); + } + + /// numberOfCaptureGroups + int get numberOfCaptureGroups { + return _objc_msgSend_15(this.pointer, _sel_numberOfCaptureGroups); + } + + /// This class method will produce a string by adding backslash escapes as necessary to the given string, to escape any characters that would otherwise be treated as pattern metacharacters. + static objc.NSString escapedPatternForString_(objc.NSString string) { + final _ret = _objc_msgSend_16(_class_NSRegularExpression, + _sel_escapedPatternForString_, string.pointer); + return objc.NSString.castFromPointer(_ret, retain: true, release: true); + } + + /// The fundamental matching method on NSRegularExpression is a block iterator. There are several additional convenience methods, for returning all matches at once, the number of matches, the first match, or the range of the first match. Each match is specified by an instance of NSTextCheckingResult (of type NSTextCheckingTypeRegularExpression) in which the overall match range is given by the range property (equivalent to rangeAtIndex:0) and any capture group ranges are given by rangeAtIndex: for indexes from 1 to numberOfCaptureGroups. {NSNotFound, 0} is used if a particular capture group does not participate in the match. + void enumerateMatchesInString_options_range_usingBlock_( + objc.NSString string, + NSMatchingOptions options, + NSRange range, + ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool block) { + _objc_msgSend_17( + this.pointer, + _sel_enumerateMatchesInString_options_range_usingBlock_, + string.pointer, + options.value, + range, + block.pointer); + } + + /// matchesInString:options:range: + objc.NSArray matchesInString_options_range_( + objc.NSString string, NSMatchingOptions options, NSRange range) { + final _ret = _objc_msgSend_18( + this.pointer, + _sel_matchesInString_options_range_, + string.pointer, + options.value, + range); + return objc.NSArray.castFromPointer(_ret, retain: true, release: true); + } + + /// numberOfMatchesInString:options:range: + int numberOfMatchesInString_options_range_( + objc.NSString string, NSMatchingOptions options, NSRange range) { + return _objc_msgSend_19( + this.pointer, + _sel_numberOfMatchesInString_options_range_, + string.pointer, + options.value, + range); + } + + /// firstMatchInString:options:range: + NSTextCheckingResult? firstMatchInString_options_range_( + objc.NSString string, NSMatchingOptions options, NSRange range) { + final _ret = _objc_msgSend_20( + this.pointer, + _sel_firstMatchInString_options_range_, + string.pointer, + options.value, + range); + return _ret.address == 0 + ? null + : NSTextCheckingResult.castFromPointer(_ret, + retain: true, release: true); + } + + /// rangeOfFirstMatchInString:options:range: + void rangeOfFirstMatchInString_options_range_(ffi.Pointer stret, + objc.NSString string, NSMatchingOptions options, NSRange range) { + objc.useMsgSendVariants + ? _objc_msgSend_21Stret( + stret, + this.pointer, + _sel_rangeOfFirstMatchInString_options_range_, + string.pointer, + options.value, + range) + : stret.ref = _objc_msgSend_21( + this.pointer, + _sel_rangeOfFirstMatchInString_options_range_, + string.pointer, + options.value, + range); + } + + /// NSRegularExpression also provides find-and-replace methods for both immutable and mutable strings. The replacement is treated as a template, with $0 being replaced by the contents of the matched range, $1 by the contents of the first capture group, and so on. Additional digits beyond the maximum required to represent the number of capture groups will be treated as ordinary characters, as will a $ not followed by digits. Backslash will escape both $ and itself. + objc.NSString stringByReplacingMatchesInString_options_range_withTemplate_( + objc.NSString string, + NSMatchingOptions options, + NSRange range, + objc.NSString templ) { + final _ret = _objc_msgSend_22( + this.pointer, + _sel_stringByReplacingMatchesInString_options_range_withTemplate_, + string.pointer, + options.value, + range, + templ.pointer); + return objc.NSString.castFromPointer(_ret, retain: true, release: true); + } + + /// replaceMatchesInString:options:range:withTemplate: + int replaceMatchesInString_options_range_withTemplate_( + objc.NSMutableString string, + NSMatchingOptions options, + NSRange range, + objc.NSString templ) { + return _objc_msgSend_23( + this.pointer, + _sel_replaceMatchesInString_options_range_withTemplate_, + string.pointer, + options.value, + range, + templ.pointer); + } + + /// For clients implementing their own replace functionality, this is a method to perform the template substitution for a single result, given the string from which the result was matched, an offset to be added to the location of the result in the string (for example, in case modifications to the string moved the result since it was matched), and a replacement template. + objc.NSString replacementStringForResult_inString_offset_template_( + NSTextCheckingResult result, + objc.NSString string, + int offset, + objc.NSString templ) { + final _ret = _objc_msgSend_24( + this.pointer, + _sel_replacementStringForResult_inString_offset_template_, + result.pointer, + string.pointer, + offset, + templ.pointer); + return objc.NSString.castFromPointer(_ret, retain: true, release: true); + } + + /// This class method will produce a string by adding backslash escapes as necessary to the given string, to escape any characters that would otherwise be treated as template metacharacters. + static objc.NSString escapedTemplateForString_(objc.NSString string) { + final _ret = _objc_msgSend_16(_class_NSRegularExpression, + _sel_escapedTemplateForString_, string.pointer); + return objc.NSString.castFromPointer(_ret, retain: true, release: true); + } + + /// init + NSRegularExpression init() { + final _ret = _objc_msgSend_25(this.pointer, _sel_init); + return NSRegularExpression.castFromPointer(_ret, + retain: true, release: true); + } + + /// new + static NSRegularExpression new1() { + final _ret = _objc_msgSend_25(_class_NSRegularExpression, _sel_new); + return NSRegularExpression.castFromPointer(_ret, + retain: false, release: true); + } + + /// allocWithZone: + static NSRegularExpression allocWithZone_(ffi.Pointer<_NSZone> zone) { + final _ret = + _objc_msgSend_26(_class_NSRegularExpression, _sel_allocWithZone_, zone); + return NSRegularExpression.castFromPointer(_ret, + retain: false, release: true); + } + + /// alloc + static NSRegularExpression alloc() { + final _ret = _objc_msgSend_25(_class_NSRegularExpression, _sel_alloc); + return NSRegularExpression.castFromPointer(_ret, + retain: false, release: true); + } +} + +late final _class_NSRegularExpression = objc.getClass("NSRegularExpression"); + +/// NSRegularExpression is a class used to represent and apply regular expressions. An instance of this class is an immutable representation of a compiled regular expression pattern and various option flags. +enum NSRegularExpressionOptions { + /// Match letters in the pattern independent of case. + NSRegularExpressionCaseInsensitive(1), + + /// Ignore whitespace and #-prefixed comments in the pattern. + NSRegularExpressionAllowCommentsAndWhitespace(2), + + /// Treat the entire pattern as a literal string. + NSRegularExpressionIgnoreMetacharacters(4), + + /// Allow . to match any character, including line separators. + NSRegularExpressionDotMatchesLineSeparators(8), + + /// Allow ^ and $ to match the start and end of lines. + NSRegularExpressionAnchorsMatchLines(16), + + /// Treat only \n as a line separator (otherwise, all standard line separators are used). + NSRegularExpressionUseUnixLineSeparators(32), + + /// Use Unicode TR#29 to specify word boundaries (otherwise, traditional regular expression word boundaries are used). + NSRegularExpressionUseUnicodeWordBoundaries(64); + + final int value; + const NSRegularExpressionOptions(this.value); + + static NSRegularExpressionOptions fromValue(int value) => switch (value) { + 1 => NSRegularExpressionCaseInsensitive, + 2 => NSRegularExpressionAllowCommentsAndWhitespace, + 4 => NSRegularExpressionIgnoreMetacharacters, + 8 => NSRegularExpressionDotMatchesLineSeparators, + 16 => NSRegularExpressionAnchorsMatchLines, + 32 => NSRegularExpressionUseUnixLineSeparators, + 64 => NSRegularExpressionUseUnicodeWordBoundaries, + _ => throw ArgumentError( + "Unknown value for NSRegularExpressionOptions: $value"), + }; +} + +late final _sel_regularExpressionWithPattern_options_error_ = + objc.registerName("regularExpressionWithPattern:options:error:"); +final _objc_msgSend_11 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedLong, + ffi.Pointer>)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + int, + ffi.Pointer>)>(); +typedef instancetype = ffi.Pointer; +typedef Dartinstancetype = objc.ObjCObjectBase; +late final _sel_initWithPattern_options_error_ = + objc.registerName("initWithPattern:options:error:"); +final _objc_msgSend_12 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + instancetype Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedLong, + ffi.Pointer>)>>() + .asFunction< + instancetype Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + int, + ffi.Pointer>)>(); +late final _sel_pattern = objc.registerName("pattern"); +final _objc_msgSend_13 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Pointer)>(); +late final _sel_options = objc.registerName("options"); +final _objc_msgSend_14 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.UnsignedLong Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + int Function( + ffi.Pointer, ffi.Pointer)>(); +late final _sel_numberOfCaptureGroups = + objc.registerName("numberOfCaptureGroups"); +final _objc_msgSend_15 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.UnsignedLong Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + int Function( + ffi.Pointer, ffi.Pointer)>(); +late final _sel_escapedPatternForString_ = + objc.registerName("escapedPatternForString:"); +final _objc_msgSend_16 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer, ffi.Pointer)>(); + +enum NSMatchingOptions { + /// Call the block periodically during long-running match operations. + NSMatchingReportProgress(1), + + /// Call the block once after the completion of any matching. + NSMatchingReportCompletion(2), + + /// Limit matches to those at the start of the search range. + NSMatchingAnchored(4), + + /// Allow matching to look beyond the bounds of the search range. + NSMatchingWithTransparentBounds(8), + + /// Prevent ^ and $ from automatically matching the beginning and end of the search range. + NSMatchingWithoutAnchoringBounds(16); + + final int value; + const NSMatchingOptions(this.value); + + static NSMatchingOptions fromValue(int value) => switch (value) { + 1 => NSMatchingReportProgress, + 2 => NSMatchingReportCompletion, + 4 => NSMatchingAnchored, + 8 => NSMatchingWithTransparentBounds, + 16 => NSMatchingWithoutAnchoringBounds, + _ => throw ArgumentError("Unknown value for NSMatchingOptions: $value"), + }; +} + +void + _ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool_fnPtrTrampoline( + ffi.Pointer block, + ffi.Pointer arg0, + int arg1, + ffi.Pointer arg2) => + block.ref.target + .cast< + ffi.NativeFunction< + ffi.Void Function(ffi.Pointer arg0, + ffi.UnsignedLong arg1, ffi.Pointer arg2)>>() + .asFunction< + void Function(ffi.Pointer, int, + ffi.Pointer)>()(arg0, arg1, arg2); +void + _ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool_closureTrampoline( + ffi.Pointer block, + ffi.Pointer arg0, + int arg1, + ffi.Pointer arg2) => + (objc.getBlockClosure(block) as void Function( + ffi.Pointer, + int, + ffi.Pointer))(arg0, arg1, arg2); + +class ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool + extends objc.ObjCBlockBase { + ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool._( + ffi.Pointer pointer, + {bool retain = false, + bool release = true}) + : super(pointer, retain: retain, release: release); + + /// Returns a block that wraps the given raw block pointer. + static ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool + castFromPointer(ffi.Pointer pointer, + {bool retain = false, bool release = false}) { + return ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool._( + pointer, + retain: retain, + release: release); + } + + /// Creates a block from a C function pointer. + /// + /// This block must be invoked by native code running on the same thread as + /// the isolate that registered it. Invoking the block on the wrong thread + /// will result in a crash. + ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool.fromFunctionPointer( + ffi.Pointer< + ffi.NativeFunction< + ffi.Void Function(ffi.Pointer arg0, + ffi.UnsignedLong arg1, ffi.Pointer arg2)>> + ptr) + : this._(objc.newPointerBlock( + _cFuncTrampoline ??= ffi.Pointer.fromFunction< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedLong, + ffi.Pointer)>( + _ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool_fnPtrTrampoline) + .cast(), + ptr.cast())); + static ffi.Pointer? _cFuncTrampoline; + + /// Creates a block from a Dart function. + /// + /// This block must be invoked by native code running on the same thread as + /// the isolate that registered it. Invoking the block on the wrong thread + /// will result in a crash. + ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool.fromFunction( + void Function(NSTextCheckingResult?, NSMatchingFlags, ffi.Pointer) + fn) + : this._(objc.newClosureBlock( + _dartFuncTrampoline ??= ffi.Pointer.fromFunction< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedLong, + ffi.Pointer)>( + _ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool_closureTrampoline) + .cast(), + (ffi.Pointer arg0, int arg1, + ffi.Pointer arg2) => + fn(arg0.address == 0 ? null : NSTextCheckingResult.castFromPointer(arg0, retain: true, release: true), NSMatchingFlags.fromValue(arg1), arg2))); + static ffi.Pointer? _dartFuncTrampoline; + + /// Creates a listener block from a Dart function. + /// + /// This is based on FFI's NativeCallable.listener, and has the same + /// capabilities and limitations. This block can be invoked from any thread, + /// but only supports void functions, and is not run synchronously. See + /// NativeCallable.listener for more details. + /// + /// Note that unlike the default behavior of NativeCallable.listener, listener + /// blocks do not keep the isolate alive. + ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool.listener( + void Function(NSTextCheckingResult?, NSMatchingFlags, ffi.Pointer) + fn) + : this._(wrapListenerBlock_ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool(objc.newClosureBlock( + (_dartFuncListenerTrampoline ??= ffi.NativeCallable, ffi.Pointer, ffi.UnsignedLong, ffi.Pointer)>.listener( + _ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool_closureTrampoline) + ..keepIsolateAlive = false) + .nativeFunction + .cast(), + (ffi.Pointer arg0, int arg1, ffi.Pointer arg2) => fn( + arg0.address == 0 + ? null + : NSTextCheckingResult.castFromPointer(arg0, retain: false, release: true), + NSMatchingFlags.fromValue(arg1), + arg2)))); + static ffi.NativeCallable< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedLong, + ffi.Pointer)>? _dartFuncListenerTrampoline; + + void call(NSTextCheckingResult? arg0, NSMatchingFlags arg1, + ffi.Pointer arg2) => + pointer.ref.invoke + .cast< + ffi.NativeFunction< + ffi.Void Function( + ffi.Pointer block, + ffi.Pointer arg0, + ffi.UnsignedLong arg1, + ffi.Pointer arg2)>>() + .asFunction< + void Function( + ffi.Pointer, + ffi.Pointer, + int, + ffi.Pointer)>()( + pointer, arg0?.pointer ?? ffi.nullptr, arg1.value, arg2); +} + +enum NSMatchingFlags { + /// Set when the block is called to report progress during a long-running match operation. + NSMatchingProgress(1), + + /// Set when the block is called after completion of any matching. + NSMatchingCompleted(2), + + /// Set when the current match operation reached the end of the search range. + NSMatchingHitEnd(4), + + /// Set when the current match depended on the location of the end of the search range. + NSMatchingRequiredEnd(8), + + /// Set when matching failed due to an internal error. + NSMatchingInternalError(16); + + final int value; + const NSMatchingFlags(this.value); + + static NSMatchingFlags fromValue(int value) => switch (value) { + 1 => NSMatchingProgress, + 2 => NSMatchingCompleted, + 4 => NSMatchingHitEnd, + 8 => NSMatchingRequiredEnd, + 16 => NSMatchingInternalError, + _ => throw ArgumentError("Unknown value for NSMatchingFlags: $value"), + }; +} + +late final _sel_enumerateMatchesInString_options_range_usingBlock_ = + objc.registerName("enumerateMatchesInString:options:range:usingBlock:"); +final _objc_msgSend_17 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedLong, + NSRange, + ffi.Pointer)>>() + .asFunction< + void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + int, + NSRange, + ffi.Pointer)>(); +late final _sel_matchesInString_options_range_ = + objc.registerName("matchesInString:options:range:"); +final _objc_msgSend_18 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedLong, + NSRange)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + int, + NSRange)>(); +late final _sel_numberOfMatchesInString_options_range_ = + objc.registerName("numberOfMatchesInString:options:range:"); +final _objc_msgSend_19 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.UnsignedLong Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedLong, + NSRange)>>() + .asFunction< + int Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + int, + NSRange)>(); +late final _sel_firstMatchInString_options_range_ = + objc.registerName("firstMatchInString:options:range:"); +final _objc_msgSend_20 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedLong, + NSRange)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + int, + NSRange)>(); +late final _sel_rangeOfFirstMatchInString_options_range_ = + objc.registerName("rangeOfFirstMatchInString:options:range:"); +final _objc_msgSend_21 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + NSRange Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedLong, + NSRange)>>() + .asFunction< + NSRange Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + int, + NSRange)>(); +final _objc_msgSend_21Stret = objc.msgSendStretPointer + .cast< + ffi.NativeFunction< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedLong, + NSRange)>>() + .asFunction< + void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + int, + NSRange)>(); +late final _sel_stringByReplacingMatchesInString_options_range_withTemplate_ = + objc.registerName( + "stringByReplacingMatchesInString:options:range:withTemplate:"); +final _objc_msgSend_22 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedLong, + NSRange, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + int, + NSRange, + ffi.Pointer)>(); +late final _sel_replaceMatchesInString_options_range_withTemplate_ = + objc.registerName("replaceMatchesInString:options:range:withTemplate:"); +final _objc_msgSend_23 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.UnsignedLong Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedLong, + NSRange, + ffi.Pointer)>>() + .asFunction< + int Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + int, + NSRange, + ffi.Pointer)>(); +late final _sel_replacementStringForResult_inString_offset_template_ = + objc.registerName("replacementStringForResult:inString:offset:template:"); +final _objc_msgSend_24 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Long, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + int, + ffi.Pointer)>(); +late final _sel_escapedTemplateForString_ = + objc.registerName("escapedTemplateForString:"); +late final _sel_init = objc.registerName("init"); +final _objc_msgSend_25 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + instancetype Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + instancetype Function( + ffi.Pointer, ffi.Pointer)>(); +late final _sel_new = objc.registerName("new"); + +final class _NSZone extends ffi.Opaque {} + +late final _sel_allocWithZone_ = objc.registerName("allocWithZone:"); +final _objc_msgSend_26 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + instancetype Function(ffi.Pointer, + ffi.Pointer, ffi.Pointer<_NSZone>)>>() + .asFunction< + instancetype Function(ffi.Pointer, + ffi.Pointer, ffi.Pointer<_NSZone>)>(); +late final _sel_alloc = objc.registerName("alloc"); +late final _sel_regularExpression = objc.registerName("regularExpression"); +final _objc_msgSend_27 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Pointer)>(); +late final _sel_phoneNumber = objc.registerName("phoneNumber"); +late final _sel_numberOfRanges = objc.registerName("numberOfRanges"); +late final _sel_rangeAtIndex_ = objc.registerName("rangeAtIndex:"); +final _objc_msgSend_28 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + NSRange Function(ffi.Pointer, + ffi.Pointer, ffi.UnsignedLong)>>() + .asFunction< + NSRange Function(ffi.Pointer, + ffi.Pointer, int)>(); +final _objc_msgSend_28Stret = objc.msgSendStretPointer + .cast< + ffi.NativeFunction< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedLong)>>() + .asFunction< + void Function(ffi.Pointer, ffi.Pointer, + ffi.Pointer, int)>(); +late final _sel_rangeWithName_ = objc.registerName("rangeWithName:"); +final _objc_msgSend_29 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + NSRange Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + NSRange Function(ffi.Pointer, + ffi.Pointer, ffi.Pointer)>(); +final _objc_msgSend_29Stret = objc.msgSendStretPointer + .cast< + ffi.NativeFunction< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + void Function(ffi.Pointer, ffi.Pointer, + ffi.Pointer, ffi.Pointer)>(); +late final _sel_resultByAdjustingRangesWithOffset_ = + objc.registerName("resultByAdjustingRangesWithOffset:"); +final _objc_msgSend_30 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer, ffi.Long)>>() + .asFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer, int)>(); +late final _sel_addressComponents = objc.registerName("addressComponents"); +late final _sel_orthographyCheckingResultWithRange_orthography_ = + objc.registerName("orthographyCheckingResultWithRange:orthography:"); +final _objc_msgSend_31 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer)>(); +late final _sel_spellCheckingResultWithRange_ = + objc.registerName("spellCheckingResultWithRange:"); +final _objc_msgSend_32 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer, NSRange)>>() + .asFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer, NSRange)>(); +late final _sel_grammarCheckingResultWithRange_details_ = + objc.registerName("grammarCheckingResultWithRange:details:"); +final _objc_msgSend_33 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer)>(); +late final _sel_dateCheckingResultWithRange_date_ = + objc.registerName("dateCheckingResultWithRange:date:"); +final _objc_msgSend_34 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer)>(); +late final _sel_dateCheckingResultWithRange_date_timeZone_duration_ = + objc.registerName("dateCheckingResultWithRange:date:timeZone:duration:"); +final _objc_msgSend_35 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer, + ffi.Pointer, + ffi.Double)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer, + ffi.Pointer, + double)>(); +late final _sel_addressCheckingResultWithRange_components_ = + objc.registerName("addressCheckingResultWithRange:components:"); +final _objc_msgSend_36 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer)>(); +late final _sel_linkCheckingResultWithRange_URL_ = + objc.registerName("linkCheckingResultWithRange:URL:"); +final _objc_msgSend_37 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer)>(); +late final _sel_quoteCheckingResultWithRange_replacementString_ = + objc.registerName("quoteCheckingResultWithRange:replacementString:"); +final _objc_msgSend_38 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer)>(); +late final _sel_dashCheckingResultWithRange_replacementString_ = + objc.registerName("dashCheckingResultWithRange:replacementString:"); +late final _sel_replacementCheckingResultWithRange_replacementString_ = + objc.registerName("replacementCheckingResultWithRange:replacementString:"); +late final _sel_correctionCheckingResultWithRange_replacementString_ = + objc.registerName("correctionCheckingResultWithRange:replacementString:"); +late final _sel_correctionCheckingResultWithRange_replacementString_alternativeStrings_ = + objc.registerName( + "correctionCheckingResultWithRange:replacementString:alternativeStrings:"); +final _objc_msgSend_39 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + NSRange, + ffi.Pointer, + ffi.Pointer)>(); +late final _sel_regularExpressionCheckingResultWithRanges_count_regularExpression_ = + objc.registerName( + "regularExpressionCheckingResultWithRanges:count:regularExpression:"); +final _objc_msgSend_40 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.UnsignedLong, + ffi.Pointer)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + int, + ffi.Pointer)>(); +late final _sel_phoneNumberCheckingResultWithRange_phoneNumber_ = + objc.registerName("phoneNumberCheckingResultWithRange:phoneNumber:"); +late final _sel_transitInformationCheckingResultWithRange_components_ = + objc.registerName("transitInformationCheckingResultWithRange:components:"); + +/// NSDataDetector +class NSDataDetector extends NSRegularExpression { + NSDataDetector._(ffi.Pointer pointer, + {bool retain = false, bool release = false}) + : super.castFromPointer(pointer, retain: retain, release: release); + + /// Constructs a [NSDataDetector] that points to the same underlying object as [other]. + NSDataDetector.castFrom(objc.ObjCObjectBase other) + : this._(other.pointer, retain: true, release: true); + + /// Constructs a [NSDataDetector] that wraps the given raw object pointer. + NSDataDetector.castFromPointer(ffi.Pointer other, + {bool retain = false, bool release = false}) + : this._(other, retain: retain, release: release); + + /// Returns whether [obj] is an instance of [NSDataDetector]. + static bool isInstance(objc.ObjCObjectBase obj) { + return _objc_msgSend_0( + obj.pointer, _sel_isKindOfClass_, _class_NSDataDetector); + } + + /// NSDataDetector is a specialized subclass of NSRegularExpression. Instead of finding matches to regular expression patterns, it matches items identified by Data Detectors, such as dates, addresses, and URLs. The checkingTypes argument should contain one or more of the types NSTextCheckingTypeDate, NSTextCheckingTypeAddress, NSTextCheckingTypeLink, NSTextCheckingTypePhoneNumber, and NSTextCheckingTypeTransitInformation. The NSTextCheckingResult instances returned will be of the appropriate types from that list. + static NSDataDetector? dataDetectorWithTypes_error_( + int checkingTypes, ffi.Pointer> error) { + final _ret = _objc_msgSend_41(_class_NSDataDetector, + _sel_dataDetectorWithTypes_error_, checkingTypes, error); + return _ret.address == 0 + ? null + : NSDataDetector.castFromPointer(_ret, retain: true, release: true); + } + + /// initWithTypes:error: + NSDataDetector? initWithTypes_error_( + int checkingTypes, ffi.Pointer> error) { + final _ret = _objc_msgSend_42( + this.pointer, _sel_initWithTypes_error_, checkingTypes, error); + return _ret.address == 0 + ? null + : NSDataDetector.castFromPointer(_ret, retain: true, release: true); + } + + /// checkingTypes + int get checkingTypes { + return _objc_msgSend_43(this.pointer, _sel_checkingTypes); + } + + /// An instance of NSRegularExpression is created from a regular expression pattern and a set of options. If the pattern is invalid, nil will be returned and an NSError will be returned by reference. The pattern syntax currently supported is that specified by ICU. + static NSRegularExpression? regularExpressionWithPattern_options_error_( + objc.NSString pattern, + NSRegularExpressionOptions options, + ffi.Pointer> error) { + final _ret = _objc_msgSend_11( + _class_NSDataDetector, + _sel_regularExpressionWithPattern_options_error_, + pattern.pointer, + options.value, + error); + return _ret.address == 0 + ? null + : NSRegularExpression.castFromPointer(_ret, + retain: true, release: true); + } + + /// initWithPattern:options:error: + NSDataDetector? initWithPattern_options_error_( + objc.NSString pattern, + NSRegularExpressionOptions options, + ffi.Pointer> error) { + final _ret = _objc_msgSend_12( + this.pointer, + _sel_initWithPattern_options_error_, + pattern.pointer, + options.value, + error); + return _ret.address == 0 + ? null + : NSDataDetector.castFromPointer(_ret, retain: true, release: true); + } + + /// This class method will produce a string by adding backslash escapes as necessary to the given string, to escape any characters that would otherwise be treated as pattern metacharacters. + static objc.NSString escapedPatternForString_(objc.NSString string) { + final _ret = _objc_msgSend_16( + _class_NSDataDetector, _sel_escapedPatternForString_, string.pointer); + return objc.NSString.castFromPointer(_ret, retain: true, release: true); + } + + /// This class method will produce a string by adding backslash escapes as necessary to the given string, to escape any characters that would otherwise be treated as template metacharacters. + static objc.NSString escapedTemplateForString_(objc.NSString string) { + final _ret = _objc_msgSend_16( + _class_NSDataDetector, _sel_escapedTemplateForString_, string.pointer); + return objc.NSString.castFromPointer(_ret, retain: true, release: true); + } + + /// init + NSDataDetector init() { + final _ret = _objc_msgSend_25(this.pointer, _sel_init); + return NSDataDetector.castFromPointer(_ret, retain: true, release: true); + } + + /// new + static NSDataDetector new1() { + final _ret = _objc_msgSend_25(_class_NSDataDetector, _sel_new); + return NSDataDetector.castFromPointer(_ret, retain: false, release: true); + } + + /// allocWithZone: + static NSDataDetector allocWithZone_(ffi.Pointer<_NSZone> zone) { + final _ret = + _objc_msgSend_26(_class_NSDataDetector, _sel_allocWithZone_, zone); + return NSDataDetector.castFromPointer(_ret, retain: false, release: true); + } + + /// alloc + static NSDataDetector alloc() { + final _ret = _objc_msgSend_25(_class_NSDataDetector, _sel_alloc); + return NSDataDetector.castFromPointer(_ret, retain: false, release: true); + } +} + +late final _class_NSDataDetector = objc.getClass("NSDataDetector"); +late final _sel_dataDetectorWithTypes_error_ = + objc.registerName("dataDetectorWithTypes:error:"); +final _objc_msgSend_41 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Uint64, + ffi.Pointer>)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + int, + ffi.Pointer>)>(); +late final _sel_initWithTypes_error_ = + objc.registerName("initWithTypes:error:"); +final _objc_msgSend_42 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + instancetype Function( + ffi.Pointer, + ffi.Pointer, + ffi.Uint64, + ffi.Pointer>)>>() + .asFunction< + instancetype Function( + ffi.Pointer, + ffi.Pointer, + int, + ffi.Pointer>)>(); +late final _sel_checkingTypes = objc.registerName("checkingTypes"); +final _objc_msgSend_43 = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Uint64 Function(ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + int Function( + ffi.Pointer, ffi.Pointer)>(); diff --git a/packages/data_detector/lib/src/data_detector_bindings_generated.dart.m b/packages/data_detector/lib/src/data_detector_bindings_generated.dart.m new file mode 100644 index 00000000..c5016ef7 --- /dev/null +++ b/packages/data_detector/lib/src/data_detector_bindings_generated.dart.m @@ -0,0 +1,11 @@ +#include + +#import +typedef void (^ListenerBlock)(NSTextCheckingResult* , NSMatchingFlags , BOOL * ); +ListenerBlock wrapListenerBlock_ObjCBlock_ffiVoid_NSTextCheckingResult_NSMatchingFlags_bool(ListenerBlock block) { + ListenerBlock wrapper = [^void(NSTextCheckingResult* arg0, NSMatchingFlags arg1, BOOL * arg2) { + block([arg0 retain], arg1, arg2); + } copy]; + [block release]; + return wrapper; +} diff --git a/packages/data_detector/pubspec.yaml b/packages/data_detector/pubspec.yaml new file mode 100644 index 00000000..1a139185 --- /dev/null +++ b/packages/data_detector/pubspec.yaml @@ -0,0 +1,34 @@ +name: data_detector +description: "A new Flutter FFI plugin project." +version: 0.0.1 +homepage: + +environment: + sdk: ^3.5.0 + flutter: '>=3.3.0' + +dependencies: + flutter: + sdk: flutter + plugin_platform_interface: ^2.0.2 + ffi: ^2.1.0 + objective_c: ^1.1.0 + +dev_dependencies: + ffigen: ^13.0.0 + flutter_test: + sdk: flutter + flutter_lints: ^4.0.0 + + +flutter: + + plugin: + platforms: + # This FFI plugin project was generated without specifying any + # platforms with the `--platform` argument. If you see the `some_platform` map below, remove it and + # then add platforms following the instruction here: + # https://flutter.dev/to/pubspec-plugin-platforms + # ------------------- + some_platform: + ffiPlugin: true diff --git a/packages/data_detector/test/data_detector_test.dart b/packages/data_detector/test/data_detector_test.dart new file mode 100644 index 00000000..c7dc1ba2 --- /dev/null +++ b/packages/data_detector/test/data_detector_test.dart @@ -0,0 +1,15 @@ +import 'dart:ui'; + +import 'package:data_detector/data_detector.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test("description", () { + final detector = DataDetector(NSTextCheckingType.NSTextCheckingTypeLink); + const str = "text: https://mixin.one"; + final results = detector.matchesInString(str); + for (final result in results) { + print('result: ${result.range.textInside(str)}'); + } + }); +}