| // Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| import 'dart:collection'; | |
| import 'package:collection/collection.dart'; | |
| import 'converter.dart'; | |
| import 'internal.dart'; | |
| import 'ns_enumerator.dart'; | |
| import 'objective_c_bindings_generated.dart'; | |
| class _NSDictionaryAdapter | |
| with | |
| MapBase<NSCopying, ObjCObject>, | |
| UnmodifiableMapMixin<NSCopying, ObjCObject> { | |
| final NSDictionary _dictionary; | |
| _NSDictionaryAdapter(this._dictionary); | |
| @override | |
| int get length => _dictionary.count; | |
| @override | |
| ObjCObject? operator [](Object? key) => | |
| key is NSCopying ? _dictionary.objectForKey(key) : null; | |
| @override | |
| Iterable<NSCopying> get keys => _NSDictionaryKeyIterable(this); | |
| @override | |
| Iterable<ObjCObject> get values => _NSDictionaryValueIterable(this); | |
| @override | |
| bool containsKey(Object? key) => this[key] != null; | |
| } | |
| extension NSDictionaryToAdapter on NSDictionary { | |
| /// Wraps this [NSDictionary] in an adapter that implements an immutable | |
| /// [Map]. | |
| /// | |
| /// This is not a conversion, doesn't create a new map, or change the | |
| /// elements. For deep conversion, use [toDartMap]. | |
| Map<NSCopying, ObjCObject> asDart() => _NSDictionaryAdapter(this); | |
| } | |
| class _NSMutableDictionaryAdapter with MapBase<NSCopying, ObjCObject> { | |
| final NSMutableDictionary _dictionary; | |
| _NSMutableDictionaryAdapter(this._dictionary); | |
| @override | |
| int get length => _dictionary.count; | |
| @override | |
| ObjCObject? operator [](Object? key) => | |
| key is NSCopying ? _dictionary.objectForKey(key) : null; | |
| @override | |
| void operator []=(NSCopying key, ObjCObject value) => | |
| NSMutableDictionary$Methods( | |
| _dictionary, | |
| ).setObject(value, forKey: NSCopying.as(key)); | |
| @override | |
| Iterable<NSCopying> get keys => _NSDictionaryAdapter(_dictionary).keys; | |
| @override | |
| Iterable<ObjCObject> get values => _NSDictionaryAdapter(_dictionary).values; | |
| @override | |
| bool containsKey(Object? key) => this[key] != null; | |
| @override | |
| void clear() => _dictionary.removeAllObjects(); | |
| @override | |
| ObjCObject? remove(Object? key) { | |
| if (key is! NSCopying) return null; | |
| final old = this[key]; | |
| _dictionary.removeObjectForKey(key); | |
| return old; | |
| } | |
| } | |
| extension NSMutableDictionaryToAdapter on NSMutableDictionary { | |
| /// Wraps this [NSMutableDictionary] in an adapter that implements [Map]. | |
| /// | |
| /// This is not a conversion, doesn't create a new map, or change the | |
| /// elements. For deep conversion, use [toDartMap]. | |
| Map<NSCopying, ObjCObject> asDart() => _NSMutableDictionaryAdapter(this); | |
| } | |
| class _NSDictionaryKeyIterable with Iterable<NSCopying> { | |
| final _NSDictionaryAdapter _adapter; | |
| _NSDictionaryKeyIterable(this._adapter); | |
| @override | |
| int get length => _adapter.length; | |
| @override | |
| Iterator<NSCopying> get iterator => | |
| _NSDictionaryKeyIterator(_adapter._dictionary.keyEnumerator().asDart()); | |
| @override | |
| bool contains(Object? key) => _adapter.containsKey(key); | |
| } | |
| class _NSDictionaryKeyIterator implements Iterator<NSCopying> { | |
| final Iterator<ObjCObject> _iterator; | |
| _NSDictionaryKeyIterator(this._iterator); | |
| @override | |
| NSCopying get current => NSCopying.as(_iterator.current); | |
| @override | |
| @pragma('vm:prefer-inline') | |
| bool moveNext() => _iterator.moveNext(); | |
| } | |
| class _NSDictionaryValueIterable with Iterable<ObjCObject> { | |
| final _NSDictionaryAdapter _adapter; | |
| _NSDictionaryValueIterable(this._adapter); | |
| @override | |
| int get length => _adapter.length; | |
| @override | |
| Iterator<ObjCObject> get iterator => | |
| _adapter._dictionary.objectEnumerator().asDart(); | |
| } |