[foundation] Add support for NSValue/CGAffineTransform and StoreValueAtAddress overload (#6887)

Support for `NSValue`/`CGAffineTransform` exists in iOS/tvOS/watchOS,
from UIKit, but not for macOS. However this will be required for the
new protocols inside CoreImage.

Also add an overload for `StoreValueAtAddress` since the original
one was deprecated but we did not provide the new alternative to
update the code.
This commit is contained in:
Sebastien Pouliot 2019-08-30 18:00:04 -04:00 коммит произвёл GitHub
Родитель bc988580d9
Коммит 9e193eaca3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 70 добавлений и 6 удалений

Просмотреть файл

@ -1,4 +1,4 @@
#ifndef __MONOTOUCH_SUPPORT_H__
#ifndef __MONOTOUCH_SUPPORT_H__
#define __MONOTOUCH_SUPPORT_H__
#ifdef __cplusplus
@ -15,6 +15,11 @@ void xamarin_start_wwan (const char *uri);
const char * xamarin_GetFolderPath (int folder);
#endif
#ifdef MONOMAC
const char *
xamarin_encode_CGAffineTransform ();
#endif
#if defined (__arm64__)
void objc_msgSend_stret (void);
void objc_msgSendSuper_stret (void);

Просмотреть файл

@ -172,3 +172,13 @@ void objc_msgSendSuper_stret (void)
#endif
#ifdef MONOMAC
// <quote>Do not hard-code this parameter as a C string.</quote>
// works on iOS (where we don't need it) and crash on macOS
const char *
xamarin_encode_CGAffineTransform ()
{
// COOP: no managed memory access: any mode.
return @encode (CGAffineTransform);
}
#endif

Просмотреть файл

@ -1,6 +1,7 @@
//
// Copyright 2010, Novell, Inc.
// Copyright 2011, 2012, 2013 Xamarin Inc
// Copyright 2019 Microsoft Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
@ -22,11 +23,14 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
#if !NO_SYSTEM_DRAWING
using System.Drawing;
#endif
using System.Runtime.InteropServices;
using CoreGraphics;
namespace Foundation {
public partial class NSValue : NSObject {
#if !COREBUILD
@ -64,6 +68,31 @@ namespace Foundation {
get { return (PointF)CGPointValue; }
}
#endif
#if MONOMAC
// @encode(CGAffineTransform) -> "{CGAffineTransform=dddddd}" but...
// using a C string crash on macOS (while it works fine on iOS)
[DllImport ("__Internal")]
extern static IntPtr xamarin_encode_CGAffineTransform ();
// The `+valueWithCGAffineTransform:` selector comes from UIKit and is not available on macOS
public unsafe static NSValue FromCGAffineTransform (CGAffineTransform tran)
{
return Create ((IntPtr) (void*) &tran, xamarin_encode_CGAffineTransform ());
}
// The `CGAffineTransformValue` selector comes from UIKit and is not available on macOS
public unsafe virtual CGAffineTransform CGAffineTransformValue {
get {
var result = new CGAffineTransform ();
// avoid potential buffer overflow since we use the older `getValue:` API to cover all platforms
// and we can cheat here with the actual string comparison (since we are the one doing it)
if (ObjCType == "{CGAffineTransform=dddddd}")
StoreValueAtAddress ((IntPtr) (void*) &result);
return result;
}
}
#endif
#endif
}
}

Просмотреть файл

@ -10879,14 +10879,19 @@ namespace Foundation
[Export ("getValue:")]
void StoreValueAtAddress (IntPtr value);
[Watch (4,0), TV (11,0), Mac (10,13), iOS (11,0)]
[Export ("getValue:size:")]
void StoreValueAtAddress (IntPtr value, nuint size);
[Export ("objCType")][Internal]
IntPtr ObjCTypePtr ();
//[Export ("initWithBytes:objCType:")][Internal]
//NSValue InitFromBytes (IntPtr byte_ptr, IntPtr char_ptr_type);
//[Export ("valueWithBytes:objCType:")][Static][Internal]
//+ (NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type;
//+ (NSValue *)value:(const void *)value withObjCType:(const char *)type;
[Static][Internal]
[Export ("valueWithBytes:objCType:")]
NSValue Create (IntPtr bytes, IntPtr objCType);
[Static]
[Export ("valueWithNonretainedObject:")]

Просмотреть файл

@ -5,6 +5,7 @@
// Rolf Bjarne Kvinge <rolf@xamarin.com>
//
// Copyright 2014 Xamarin Inc. All rights reserved.
// Copyright 2019 Microsoft Corporation
//
using System;
@ -334,6 +335,22 @@ namespace MonoTouchFixtures.CoreGraphics {
Assert.AreEqual ((nfloat) 1.0, transform.x0, "x0");
Assert.AreEqual ((nfloat) (-2.0), transform.y0, "y0");
}
[Test]
public void NSValueRoundtrip ()
{
var transform = new CGAffineTransform (1, 2, 3, 4, 5, 6);
// looks simplistic but that NSValue logic is implemented by "us" on macOS
using (var nsv = NSValue.FromCGAffineTransform (transform)) {
var tback = nsv.CGAffineTransformValue;
Assert.AreEqual ((nfloat)1, tback.xx, "xx");
Assert.AreEqual ((nfloat)2, tback.yx, "yx");
Assert.AreEqual ((nfloat)3, tback.xy, "xy");
Assert.AreEqual ((nfloat)4, tback.yy, "yy");
Assert.AreEqual ((nfloat)5, tback.x0, "x0");
Assert.AreEqual ((nfloat)6, tback.y0, "y0");
}
}
}

Просмотреть файл

@ -417,7 +417,6 @@
!missing-selector! +NSURLRequest::requestWithURL:cachePolicy:timeoutInterval: not bound
!missing-selector! +NSURLRequest::supportsSecureCoding not bound
!missing-selector! +NSValue::value:withObjCType: not bound
!missing-selector! +NSValue::valueWithBytes:objCType: not bound
!missing-selector! +NSXPCInterface::interfaceWithProtocol: not bound
!missing-selector! NSArray::addObserver:forKeyPath:options:context: not bound
!missing-selector! NSArray::arrayByAddingObject: not bound
@ -837,7 +836,6 @@
!missing-selector! NSURLProtocol::task not bound
!missing-selector! NSURLRequest::HTTPShouldUsePipelining not bound
!missing-selector! NSUUID::initWithUUIDBytes: not bound
!missing-selector! NSValue::getValue:size: not bound
!missing-selector! NSValue::initWithBytes:objCType: not bound
!missing-selector! NSXPCConnection::auditSessionIdentifier not bound
!missing-selector! NSXPCConnection::effectiveGroupIdentifier not bound