Add EdgeInsets missing function in value

This commit is contained in:
Matvii Jarosh 2024-11-21 13:01:31 +02:00
parent da73bc5e9b
commit 410b295b01
7 changed files with 134 additions and 0 deletions

View file

@ -1,3 +1,12 @@
2024-11-21 Matvii Jarosh <matviijarosh@gmail.com>
* NSValue: add valueWithEdgeInsets and edgeInsetsValue.
* typeEncodingHelper.h: add NSINSETS_ENCODING_PREFIX and
IS_NSINSETS_ENCODING and update comment.
* type_encoding.m: add test NSINSETS_ENCODING_PREFIX.
* GSConcreteValueTamplate.m: add GSEdgeInsetsValue.
* GSConcreteValue.m: add TYPE_ORDER 6.
2024-11-19 Richard Frith-Macdonald <rfm@gnu.org> 2024-11-19 Richard Frith-Macdonald <rfm@gnu.org>
* GSMime: fixed buffer overrun in rare circumstances when decoding * GSMime: fixed buffer overrun in rare circumstances when decoding

View file

@ -96,6 +96,14 @@ GS_EXPORT_CLASS
*/ */
+ (NSValue*) valueWithSize: (NSSize)size; + (NSValue*) valueWithSize: (NSSize)size;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
/**
* Convenience method to create instance holding an <code>NSEdgeInsets</code>
* structure.
*/
+ (NSValue*) valueWithEdgeInsets: (NSEdgeInsets)insets;
#endif
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
/** /**
* Synonym for value:withObjCType: . * Synonym for value:withObjCType: .
@ -166,6 +174,14 @@ GS_EXPORT_CLASS
*/ */
- (NSPoint) pointValue; - (NSPoint) pointValue;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
/**
* If receiver was initialized with an <code>NSEdgeInsets</code> value, return it,
* else raises <code>NSInternalInconsistencyException</code>.
*/
- (NSEdgeInsets) edgeInsetsValue;
#endif
@end @end
/** /**

View file

@ -50,3 +50,7 @@
#include "GSConcreteValueTemplate.m" #include "GSConcreteValueTemplate.m"
#undef TYPE_ORDER #undef TYPE_ORDER
#define TYPE_ORDER 6
#include "GSConcreteValueTemplate.m"
#undef TYPE_ORDER

View file

@ -79,6 +79,15 @@
# define GSTemplateValue GSSizeValue # define GSTemplateValue GSSizeValue
# define TYPE_METHOD sizeValue # define TYPE_METHOD sizeValue
# define TYPE_NAME NSSize # define TYPE_NAME NSSize
#elif TYPE_ORDER == 6
@interface GSEdgeInsetsValue : NSValue
{
NSEdgeInsets data;
}
@end
# define GSTemplateValue GSEdgeInsetsValue
# define TYPE_METHOD edgeInsetsValue
# define TYPE_NAME NSEdgeInsets
#endif #endif
@implementation GSTemplateValue @implementation GSTemplateValue
@ -164,6 +173,11 @@
return YES; return YES;
else else
return NO; return NO;
#elif TYPE_ORDER == 6
if (data.top == val.top && data.left == val.left && data.bottom == val.bottom && data.right == val.right)
return YES;
else
return NO;
#endif #endif
} }
return NO; return NO;
@ -213,6 +227,18 @@
for (i = 0; i < sizeof(double); i++) for (i = 0; i < sizeof(double); i++)
hash += val.c[i]; hash += val.c[i];
return hash; return hash;
#elif TYPE_ORDER == 6
union {
double d;
unsigned char c[sizeof(double)];
} val;
NSUInteger hash = 0;
unsigned int i;
val.d = data.top + data.left + data.bottom + data.right;
for (i = 0; i < sizeof(double); i++)
hash += val.c[i];
return hash;
#endif #endif
} }
@ -241,6 +267,9 @@
return NSStringFromRect(data); return NSStringFromRect(data);
#elif TYPE_ORDER == 5 #elif TYPE_ORDER == 5
return NSStringFromSize(data); return NSStringFromSize(data);
#elif TYPE_ORDER == 6
return [NSString stringWithFormat:@"{top = %.2f, left = %.2f, bottom = %.2f, right = %.2f}",
data.top, data.left, data.bottom, data.right];
#endif #endif
} }

View file

@ -35,6 +35,7 @@
#import "Foundation/NSMapTable.h" #import "Foundation/NSMapTable.h"
#import "Foundation/NSLock.h" #import "Foundation/NSLock.h"
#import "Foundation/NSData.h" #import "Foundation/NSData.h"
#import "Foundation/NSGeometry.h"
#import "GSPThread.h" #import "GSPThread.h"
@interface GSPlaceholderValue : NSValue @interface GSPlaceholderValue : NSValue
@ -64,6 +65,11 @@
@class NSDataStatic; // Needed for decoding. @class NSDataStatic; // Needed for decoding.
@interface NSDataStatic : NSData // Help the compiler @interface NSDataStatic : NSData // Help the compiler
@end @end
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
@class GSEdgeInsetsValueValue;
@interface GSEdgeInsetsValue : NSObject // Help the compiler
@end
#endif
static Class abstractClass; static Class abstractClass;
@ -75,6 +81,9 @@ static Class rangeValueClass;
static Class rectValueClass; static Class rectValueClass;
static Class sizeValueClass; static Class sizeValueClass;
static Class GSPlaceholderValueClass; static Class GSPlaceholderValueClass;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
static Class edgeInsetsValueClass;
#endif
static GSPlaceholderValue *defaultPlaceholderValue; static GSPlaceholderValue *defaultPlaceholderValue;
@ -128,6 +137,9 @@ static gs_mutex_t placeholderLock = GS_MUTEX_INIT_STATIC;
rectValueClass = [GSRectValue class]; rectValueClass = [GSRectValue class];
sizeValueClass = [GSSizeValue class]; sizeValueClass = [GSSizeValue class];
GSPlaceholderValueClass = [GSPlaceholderValue class]; GSPlaceholderValueClass = [GSPlaceholderValue class];
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
edgeInsetsValueClass = [GSEdgeInsetsValue class];
#endif
/* /*
* Set up infrastructure for placeholder values. * Set up infrastructure for placeholder values.
@ -217,6 +229,10 @@ static gs_mutex_t placeholderLock = GS_MUTEX_INIT_STATIC;
theClass = rectValueClass; theClass = rectValueClass;
else if (strcmp(@encode(NSSize), type) == 0) else if (strcmp(@encode(NSSize), type) == 0)
theClass = sizeValueClass; theClass = sizeValueClass;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
else if (strcmp(@encode(NSEdgeInsets), type) == 0)
theClass = edgeInsetsValueClass;
#endif
/* Try for equivalent types match. /* Try for equivalent types match.
*/ */
@ -232,6 +248,10 @@ static gs_mutex_t placeholderLock = GS_MUTEX_INIT_STATIC;
theClass = rectValueClass; theClass = rectValueClass;
else if (GSSelectorTypesMatch(@encode(NSSize), type)) else if (GSSelectorTypesMatch(@encode(NSSize), type))
theClass = sizeValueClass; theClass = sizeValueClass;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
else if (GSSelectorTypesMatch(@encode(NSEdgeInsets), type))
theClass = edgeInsetsValueClass;
#endif
return theClass; return theClass;
} }
@ -314,6 +334,17 @@ static gs_mutex_t placeholderLock = GS_MUTEX_INIT_STATIC;
return AUTORELEASE(theObj); return AUTORELEASE(theObj);
} }
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
+ (NSValue*) valueWithEdgeInsets: (NSEdgeInsets)insets
{
NSValue *theObj;
theObj = [edgeInsetsValueClass allocWithZone: NSDefaultMallocZone()];
theObj = [theObj initWithBytes: &insets objCType: @encode(NSEdgeInsets)];
return AUTORELEASE(theObj);
}
#endif
+ (NSValue*) valueFromString: (NSString *)string + (NSValue*) valueFromString: (NSString *)string
{ {
NSDictionary *dict = [string propertyList]; NSDictionary *dict = [string propertyList];
@ -424,6 +455,14 @@ static gs_mutex_t placeholderLock = GS_MUTEX_INIT_STATIC;
return NSMakePoint(0,0); return NSMakePoint(0,0);
} }
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
- (NSEdgeInsets) edgeInsetsValue
{
[self subclassResponsibility: _cmd];
return NSEdgeInsetsMake(0,0,0,0);
}
#endif
- (Class) classForCoder - (Class) classForCoder
{ {
return abstractClass; return abstractClass;
@ -468,6 +507,15 @@ static gs_mutex_t placeholderLock = GS_MUTEX_INIT_STATIC;
[coder encodeValueOfObjCType: objctype at: &v]; [coder encodeValueOfObjCType: objctype at: &v];
return; return;
} }
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
else if (strncmp(NSINSETS_ENCODING_PREFIX, objctype, strlen(NSINSETS_ENCODING_PREFIX)) == 0)
{
NSEdgeInsets v = [self edgeInsetsValue];
[coder encodeValueOfObjCType: objctype at: &v];
return;
}
#endif
NSGetSizeAndAlignment(objctype, &tsize, NULL); NSGetSizeAndAlignment(objctype, &tsize, NULL);
data = (void *)NSZoneMalloc([self zone], tsize); data = (void *)NSZoneMalloc([self zone], tsize);
@ -517,6 +565,10 @@ static gs_mutex_t placeholderLock = GS_MUTEX_INIT_STATIC;
c = [abstractClass valueClassWithObjCType: @encode(NSRect)]; c = [abstractClass valueClassWithObjCType: @encode(NSRect)];
else if (strncmp(NSRANGE_ENCODING_PREFIX, objctype, strlen(NSRANGE_ENCODING_PREFIX)) == 0) else if (strncmp(NSRANGE_ENCODING_PREFIX, objctype, strlen(NSRANGE_ENCODING_PREFIX)) == 0)
c = [abstractClass valueClassWithObjCType: @encode(NSRange)]; c = [abstractClass valueClassWithObjCType: @encode(NSRange)];
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
else if (strncmp(NSINSETS_ENCODING_PREFIX, objctype, strlen(NSINSETS_ENCODING_PREFIX)) == 0)
c = [abstractClass valueClassWithObjCType: @encode(NSEdgeInsets)];
#endif
else else
c = [abstractClass valueClassWithObjCType: objctype]; c = [abstractClass valueClassWithObjCType: objctype];
o = [c allocWithZone: [coder objectZone]]; o = [c allocWithZone: [coder objectZone]];
@ -556,6 +608,16 @@ static gs_mutex_t placeholderLock = GS_MUTEX_INIT_STATIC;
DESTROY(self); DESTROY(self);
return [o initWithBytes: &v objCType: @encode(NSRect)]; return [o initWithBytes: &v objCType: @encode(NSRect)];
} }
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
else if (c == edgeInsetsValueClass)
{
NSEdgeInsets v;
[coder decodeValueOfObjCType: @encode(NSEdgeInsets) at: &v];
DESTROY(self);
return [o initWithBytes: &v objCType: @encode(NSEdgeInsets)];
}
#endif
} }
if (ver < 2) if (ver < 2)
@ -590,6 +652,16 @@ static gs_mutex_t placeholderLock = GS_MUTEX_INIT_STATIC;
[coder decodeValueOfObjCType: @encode(NSRect) at: &v]; [coder decodeValueOfObjCType: @encode(NSRect) at: &v];
o = [o initWithBytes: &v objCType: @encode(NSRect)]; o = [o initWithBytes: &v objCType: @encode(NSRect)];
} }
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
else if (c == edgeInsetsValueClass)
{
NSEdgeInsets v;
[coder decodeValueOfObjCType: @encode(NSEdgeInsets) at: &v];
o = [o initWithBytes: &v objCType: @encode(NSEdgeInsets)];
}
#endif
else else
{ {
unsigned char *data; unsigned char *data;

View file

@ -36,6 +36,7 @@
* @encoding(CGSize) -> {CGSize=dd} * @encoding(CGSize) -> {CGSize=dd}
* @encoding(NSRange) -> {_NSRange=QQ} * @encoding(NSRange) -> {_NSRange=QQ}
* @encoding(CFRange) -> {?=qq} * @encoding(CFRange) -> {?=qq}
* @encoding(NSEdgeInsets) -> {NSEdgeInsets=dddd}
* *
* Note that NSRange and CFRange are not toll-free bridged. * Note that NSRange and CFRange are not toll-free bridged.
* You cannot pass a CFRange to +[NSValue valueWithRange:] * You cannot pass a CFRange to +[NSValue valueWithRange:]
@ -49,11 +50,13 @@
static const char *CGPOINT_ENCODING_PREFIX = "{CGPoint="; static const char *CGPOINT_ENCODING_PREFIX = "{CGPoint=";
static const char *CGSIZE_ENCODING_PREFIX = "{CGSize="; static const char *CGSIZE_ENCODING_PREFIX = "{CGSize=";
static const char *CGRECT_ENCODING_PREFIX = "{CGRect="; static const char *CGRECT_ENCODING_PREFIX = "{CGRect=";
static const char *NSINSETS_ENCODING_PREFIX __attribute__((used)) = "{NSEdgeInsets=";
static const char *NSRANGE_ENCODING_PREFIX = "{_NSRange="; static const char *NSRANGE_ENCODING_PREFIX = "{_NSRange=";
#define IS_CGPOINT_ENCODING(encoding) (strncmp(encoding, CGPOINT_ENCODING_PREFIX, strlen(CGPOINT_ENCODING_PREFIX)) == 0) #define IS_CGPOINT_ENCODING(encoding) (strncmp(encoding, CGPOINT_ENCODING_PREFIX, strlen(CGPOINT_ENCODING_PREFIX)) == 0)
#define IS_CGSIZE_ENCODING(encoding) (strncmp(encoding, CGSIZE_ENCODING_PREFIX, strlen(CGSIZE_ENCODING_PREFIX)) == 0) #define IS_CGSIZE_ENCODING(encoding) (strncmp(encoding, CGSIZE_ENCODING_PREFIX, strlen(CGSIZE_ENCODING_PREFIX)) == 0)
#define IS_CGRECT_ENCODING(encoding) (strncmp(encoding, CGRECT_ENCODING_PREFIX, strlen(CGRECT_ENCODING_PREFIX)) == 0) #define IS_CGRECT_ENCODING(encoding) (strncmp(encoding, CGRECT_ENCODING_PREFIX, strlen(CGRECT_ENCODING_PREFIX)) == 0)
#define IS_NSINSETS_ENCODING(encoding) (strncmp(encoding, NSINSETS_ENCODING_PREFIX, strlen(NSINSETS_ENCODING_PREFIX)) == 0)
#define IS_NSRANGE_ENCODING(encoding) (strncmp(encoding, NSRANGE_ENCODING_PREFIX, strlen(NSRANGE_ENCODING_PREFIX)) == 0) #define IS_NSRANGE_ENCODING(encoding) (strncmp(encoding, NSRANGE_ENCODING_PREFIX, strlen(NSRANGE_ENCODING_PREFIX)) == 0)
#endif /* __TYPE_ENCODING_HELPER_H */ #endif /* __TYPE_ENCODING_HELPER_H */

View file

@ -9,6 +9,7 @@ int main(int argc, char *argv[]) {
PASS(strncmp(@encode(NSPoint), CGPOINT_ENCODING_PREFIX, strlen(CGPOINT_ENCODING_PREFIX)) == 0, "CGPoint encoding"); PASS(strncmp(@encode(NSPoint), CGPOINT_ENCODING_PREFIX, strlen(CGPOINT_ENCODING_PREFIX)) == 0, "CGPoint encoding");
PASS(strncmp(@encode(NSSize), CGSIZE_ENCODING_PREFIX, strlen(CGSIZE_ENCODING_PREFIX)) == 0, "CGSize encoding"); PASS(strncmp(@encode(NSSize), CGSIZE_ENCODING_PREFIX, strlen(CGSIZE_ENCODING_PREFIX)) == 0, "CGSize encoding");
PASS(strncmp(@encode(NSRect), CGRECT_ENCODING_PREFIX, strlen(CGRECT_ENCODING_PREFIX)) == 0, "CGRect encoding"); PASS(strncmp(@encode(NSRect), CGRECT_ENCODING_PREFIX, strlen(CGRECT_ENCODING_PREFIX)) == 0, "CGRect encoding");
PASS(strncmp(@encode(NSEdgeInsets), NSINSETS_ENCODING_PREFIX, strlen(NSINSETS_ENCODING_PREFIX)) == 0, "NSEdgeInsets encoding");
PASS(strncmp(@encode(NSRange), NSRANGE_ENCODING_PREFIX, strlen(NSRANGE_ENCODING_PREFIX)) == 0, "NSRange encoding"); PASS(strncmp(@encode(NSRange), NSRANGE_ENCODING_PREFIX, strlen(NSRANGE_ENCODING_PREFIX)) == 0, "NSRange encoding");
END_SET("Known Struct Type Encodings") END_SET("Known Struct Type Encodings")