Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add EdgeInsets missing function in value #470

Merged
merged 4 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
2024-11-25 Matvii Jarosh <[email protected]>

* NSInvocation.h: add enum _NSObjCValueType and
typedef structNSObjCValue. There are no functions not implemented
in NSInvocation.h left.
* MISSING:

2024-11-21 Matvii Jarosh <[email protected]>

* 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 <[email protected]>

* GSMime: fixed buffer overrun in rare circumstances when decoding
Expand Down
42 changes: 42 additions & 0 deletions Headers/Foundation/NSInvocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#import <GNUstepBase/GSVersionMacros.h>

#import <Foundation/NSMethodSignature.h>
#include <stdbool.h>

#if defined(__cplusplus)
extern "C" {
Expand Down Expand Up @@ -154,6 +155,47 @@ GS_EXPORT_CLASS
[NSInvocation _returnInvocationAndDestroyProxy: __proxy]; \
})

typedef NS_ENUM(char, _NSObjCValueType)
{
NSObjCArrayType = '[',
NSObjCBitfield = 'b',
NSObjCBoolType = 'B',
NSObjCCharType = 'c',
NSObjCDoubleType = 'd',
NSObjCFloatType = 'f',
NSObjCLonglongType = 'q',
NSObjCLongType = 'l',
NSObjCNoType = '\0',
NSObjCObjectType = '@',
NSObjCPointerType = '^',
NSObjCSelectorType = ':',
NSObjCShortType = 's',
NSObjCStringType = '*',
NSObjCStructType = '{',
NSObjCUnionType = '(',
NSObjCVoidType = 'v',
};

typedef struct
{
_NSObjCValueType type;
union
{
bool boolValue;
char charValue;
double doubleValue;
float floatValue;
long long longlongValue;
long longValue;
id objectValue;
void *pointerValue;
SEL selectorValue;
short shortValue;
char *cStringLocation;
void *structLocation;
} value;
} NSObjCValue;

#if defined(__cplusplus)
}
#endif
Expand Down
16 changes: 16 additions & 0 deletions Headers/Foundation/NSValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ GS_EXPORT_CLASS
*/
+ (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)
/**
* Synonym for value:withObjCType: .
Expand Down Expand Up @@ -166,6 +174,14 @@ GS_EXPORT_CLASS
*/
- (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

/**
Expand Down
6 changes: 1 addition & 5 deletions MISSING
Original file line number Diff line number Diff line change
Expand Up @@ -257,12 +257,7 @@ NSIndexSet:
- enumerateRangesUsingBlock:
- enumerateRangesWithOptions:usingBlock:
- enumerateRangesInRange:options:usingBlock:
-------------------------------------------------------------
NSInvocation:
<stdbool.h>

enum _NSObjCValueType
typedef struct NSObjCValue
-------------------------------------------------------------
NSKeyedArchiver:
<NSGeometry.h>
Expand Down Expand Up @@ -885,3 +880,4 @@ Good headers:
<NSXMLDTD.h>
<NSXMLDTDNode.h>
<NSXMLElement.h>
<NSInvocation.h>
4 changes: 4 additions & 0 deletions Source/GSConcreteValue.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,7 @@
#include "GSConcreteValueTemplate.m"
#undef TYPE_ORDER

#define TYPE_ORDER 6
#include "GSConcreteValueTemplate.m"
#undef TYPE_ORDER

29 changes: 29 additions & 0 deletions Source/GSConcreteValueTemplate.m
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ @interface GSSizeValue : NSValue
# define GSTemplateValue GSSizeValue
# define TYPE_METHOD sizeValue
# 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

@implementation GSTemplateValue
Expand Down Expand Up @@ -164,6 +173,11 @@ - (BOOL) isEqualToValue: (NSValue*)aValue
return YES;
else
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
}
return NO;
Expand Down Expand Up @@ -213,6 +227,18 @@ - (NSUInteger) hash
for (i = 0; i < sizeof(double); i++)
hash += val.c[i];
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
}

Expand Down Expand Up @@ -241,6 +267,9 @@ - (NSString *) description
return NSStringFromRect(data);
#elif TYPE_ORDER == 5
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
}

Expand Down
72 changes: 72 additions & 0 deletions Source/NSValue.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#import "Foundation/NSMapTable.h"
#import "Foundation/NSLock.h"
#import "Foundation/NSData.h"
#import "Foundation/NSGeometry.h"
#import "GSPThread.h"

@interface GSPlaceholderValue : NSValue
Expand Down Expand Up @@ -64,6 +65,11 @@ @interface GSSizeValue : NSObject // Help the compiler
@class NSDataStatic; // Needed for decoding.
@interface NSDataStatic : NSData // Help the compiler
@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;
Expand All @@ -75,6 +81,9 @@ @interface NSDataStatic : NSData // Help the compiler
static Class rectValueClass;
static Class sizeValueClass;
static Class GSPlaceholderValueClass;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST)
static Class edgeInsetsValueClass;
#endif


static GSPlaceholderValue *defaultPlaceholderValue;
Expand Down Expand Up @@ -128,6 +137,9 @@ + (void) initialize
rectValueClass = [GSRectValue class];
sizeValueClass = [GSSizeValue 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.
Expand Down Expand Up @@ -217,6 +229,10 @@ + (Class) valueClassWithObjCType: (const char *)type
theClass = rectValueClass;
else if (strcmp(@encode(NSSize), type) == 0)
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.
*/
Expand All @@ -232,6 +248,10 @@ + (Class) valueClassWithObjCType: (const char *)type
theClass = rectValueClass;
else if (GSSelectorTypesMatch(@encode(NSSize), type))
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;
}
Expand Down Expand Up @@ -314,6 +334,17 @@ + (NSValue*) valueWithSize: (NSSize)size
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
{
NSDictionary *dict = [string propertyList];
Expand Down Expand Up @@ -424,6 +455,14 @@ - (NSPoint) pointValue
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
{
return abstractClass;
Expand Down Expand Up @@ -468,6 +507,15 @@ - (void) encodeWithCoder: (NSCoder *)coder
[coder encodeValueOfObjCType: objctype at: &v];
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);
data = (void *)NSZoneMalloc([self zone], tsize);
Expand Down Expand Up @@ -517,6 +565,10 @@ - (id) initWithCoder: (NSCoder *)coder
c = [abstractClass valueClassWithObjCType: @encode(NSRect)];
else if (strncmp(NSRANGE_ENCODING_PREFIX, objctype, strlen(NSRANGE_ENCODING_PREFIX)) == 0)
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
c = [abstractClass valueClassWithObjCType: objctype];
o = [c allocWithZone: [coder objectZone]];
Expand Down Expand Up @@ -556,6 +608,16 @@ - (id) initWithCoder: (NSCoder *)coder
DESTROY(self);
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)
Expand Down Expand Up @@ -590,6 +652,16 @@ - (id) initWithCoder: (NSCoder *)coder
[coder decodeValueOfObjCType: @encode(NSRect) at: &v];
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
{
unsigned char *data;
Expand Down
3 changes: 3 additions & 0 deletions Source/typeEncodingHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
* @encoding(CGSize) -> {CGSize=dd}
* @encoding(NSRange) -> {_NSRange=QQ}
* @encoding(CFRange) -> {?=qq}
* @encoding(NSEdgeInsets) -> {NSEdgeInsets=dddd}
*
* Note that NSRange and CFRange are not toll-free bridged.
* You cannot pass a CFRange to +[NSValue valueWithRange:]
Expand All @@ -49,11 +50,13 @@
static const char *CGPOINT_ENCODING_PREFIX = "{CGPoint=";
static const char *CGSIZE_ENCODING_PREFIX = "{CGSize=";
static const char *CGRECT_ENCODING_PREFIX = "{CGRect=";
static const char *NSINSETS_ENCODING_PREFIX __attribute__((used)) = "{NSEdgeInsets=";
static const char *NSRANGE_ENCODING_PREFIX = "{_NSRange=";

#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_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)

#endif /* __TYPE_ENCODING_HELPER_H */
1 change: 1 addition & 0 deletions Tests/base/KVC/type_encoding.m
Original file line number Diff line number Diff line change
Expand Up @@ -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(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(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");

END_SET("Known Struct Type Encodings")
Expand Down