ObjFW  Check-in [237a4e91a9]

Overview
Comment:OFValue: Add support for pointers and objects
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 237a4e91a9ff0cbed89ce0330dd7a60e946eb45163372637c89dc00af11d4d1a
User & Date: js on 2018-01-21 01:38:18
Other Links: manifest | tags
Context
2018-01-21
02:02
README.md: Update for removed Xcode project check-in: 95f945430a user: js tags: trunk
01:38
OFValue: Add support for pointers and objects check-in: 237a4e91a9 user: js tags: trunk
00:48
Initial OFValue implementation check-in: 4a08ae655b user: js tags: trunk
Changes

Modified src/Makefile from [56da1c535b] to [ab44d84097].

168
169
170
171
172
173
174


175
176
177
178
179
180
181
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183







+
+







	OFMutableArray_adjacent.m	\
	OFMutableDictionary_hashtable.m	\
	OFMutableSet_hashtable.m	\
	OFMutableString_UTF8.m		\
	OFSet_hashtable.m		\
	OFString_UTF8.m			\
	OFValue_bytes.m			\
	OFValue_nonretainedObject.m	\
	OFValue_pointer.m		\
	${AUTORELEASE_M}		\
	${FOUNDATION_COMPAT_M}		\
	${INSTANCE_M}
SRCS_FILES += OFSettings_INIFile.m	\
	      OFURLHandler_file.m
SRCS_SOCKETS += OFKernelEventObserver.m			\
		${OFKERNELEVENTOBSERVER_EPOLL_M}	\

Modified src/OFValue.h from [e0eab57137] to [0cf113a505].

24
25
26
27
28
29
30
31















32
33
34
35
36
37
38
39
40
41
42
43






















44
45
46
47
48
49
50
51
52
53
54























55
56
57
58
59
60
61
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120







-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+












+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+











+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







 *
 * @brief A class for storing arbitrary values in an object.
 */
@interface OFValue: OFObject
/*!
 * @brief The ObjC type encoding of the value.
 */
@property (nonatomic, readonly) const char *objCType;
@property (readonly, nonatomic) const char *objCType;

/*!
 * @brief The value as a pointer to void.
 *
 * If the value is not pointer-sized, @ref OFInvalidFormatException is thrown.
 */
@property (readonly, nonatomic) void *pointerValue;

/*!
 * @brief The value as a non-retained object.
 *
 * If the value is not pointer-sized, @ref OFInvalidFormatException is thrown.
 */
@property (readonly, nonatomic) id nonretainedObjectValue;

/*!
 * @brief Creates a new, autorelease OFValue with the specified bytes of the
 *	  specified type.
 *
 * @param bytes The bytes containing the value
 * @param objCType The ObjC type encoding for the value
 * @return A new, autoreleased OFValue
 */
+ (instancetype)valueWithBytes: (const void *)bytes
		      objCType: (const char *)objCType;

/*!
 * @brief Creates a new, autoreleased OFValue containing the specified pointer.
 *
 * Only the raw value of the pointer is stored and no data will be copied.
 *
 * @param pointer The pointer the OFValue should contain
 * @return A new, autoreleased OFValue
 */
+ (instancetype)valueWithPointer: (const void *)pointer;

/*!
 * @brief Creates a new, autoreleased OFValue containing the specified
 *	  non-retained object.
 *
 * The object is not retained, which makes this useful for storing objects in
 * collections without retaining them.
 *
 * @param object The object the OFValue should contain without retaining it
 * @return A new, autoreleased OFValue
 */
+ (instancetype)valueWithNonretainedObject: (id)object;

/*!
 * @brief Initializes an already allocated OFValue with the specified bytes of
 *	  the specified type.
 *
 * @param bytes The bytes containing the value
 * @param objCType The ObjC type encoding for the value
 * @return An initialized OFValue
 */
- (instancetype)initWithBytes: (const void *)bytes
		     objCType: (const char *)objCType;

/*!
 * @brief Initializes an already allocated OFValue containing the specified
 *	  pointer.
 *
 * Only the raw value of the pointer is stored and no data will be copied.
 *
 * @param pointer The pointer the OFValue should contain
 * @return An initialized OFValue
 */
- (instancetype)initWithPointer: (const void *)pointer;

/*!
 * @brief Initializes an already allocated OFValue containing the specified
 *	  non-retained object.
 *
 * The object is not retained, which makes this useful for storing objects in
 * collections without retaining them.
 *
 * @param object The object the OFValue should contain without retaining it
 * @return An initialized OFValue
 */
- (instancetype)initWithNonretainedObject: (id)object;

/*!
 * @brief Gets the value.
 *
 * If the specified size does not match, this raises an
 * @ref OFOutOfRangeException.
 *
 * @param value The buffer to copy the value into

Modified src/OFValue.m from [a76d433362] to [f9fd1f2d0c].

13
14
15
16
17
18
19


20
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37











38
39
40
41
42
43
44
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58







+
+


+
















+
+
+
+
+
+
+
+
+
+
+







 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFValue.h"
#import "OFValue_bytes.h"
#import "OFValue_nonretainedObject.h"
#import "OFValue_pointer.h"
#import "OFMethodSignature.h"

#import "OFInvalidFormatException.h"
#import "OFOutOfMemoryException.h"

static struct {
	Class isa;
} placeholder;

@interface OFValue_placeholder: OFValue
@end

@implementation OFValue_placeholder
- (instancetype)initWithBytes: (const void *)bytes
		     objCType: (const char *)objCType
{
	return (id)[[OFValue_bytes alloc] initWithBytes: bytes
					       objCType: objCType];
}

- (instancetype)initWithPointer: (const void *)pointer
{
	return (id)[[OFValue_pointer alloc] initWithPointer: pointer];
}

- (instancetype)initWithNonretainedObject: (id)object
{
	return (id)[[OFValue_nonretainedObject alloc]
	    initWithNonretainedObject: object];
}
@end

@implementation OFValue
+ (void)initialize
{
	if (self == [OFValue class])
		placeholder.isa = [OFValue_placeholder class];
54
55
56
57
58
59
60










61
62
63
64










65
66
67
68
69
70
71
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105







+
+
+
+
+
+
+
+
+
+




+
+
+
+
+
+
+
+
+
+








+ (instancetype)valueWithBytes: (const void *)bytes
		      objCType: (const char *)objCType
{
	return [[[self alloc] initWithBytes: bytes
				   objCType: objCType] autorelease];
}

+ (instancetype)valueWithPointer: (const void *)pointer
{
	return [[[self alloc] initWithPointer: pointer] autorelease];
}

+ (instancetype)valueWithNonretainedObject: (id)object
{
	return [[[self alloc] initWithNonretainedObject: object] autorelease];
}

- (instancetype)initWithBytes: (const void *)bytes
		     objCType: (const char *)objCType
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithPointer: (const void *)pointer
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithNonretainedObject: (id)object
{
	OF_INVALID_INIT_METHOD
}

- (bool)isEqual: (id)object
{
	const char *objCType;
	size_t size;
137
138
139
140
141
142
143




















144
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

}

- (void)getValue: (void *)value
	    size: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)pointerValue
{
	void *ret;

	[self getValue: &ret
		  size: sizeof(ret)];

	return ret;
}

- (id)nonretainedObjectValue
{
	id ret;

	[self getValue: &ret
		  size: sizeof(ret)];

	return ret;
}
@end

Modified src/OFValue_bytes.h from [bcfee3a6ca] to [4e064aa6c2].

1
2

3

4
5
6
7
8
9
10
1
2
3

4
5
6
7
8
9
10
11


+
-
+







/*
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
 *               2018
 *               2018 *   Jonathan Schleifer <js@heap.zone>
 *   Jonathan Schleifer <js@heap.zone>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *

Added src/OFValue_nonretainedObject.h version [099847e639].





























1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
 *               2018
 *   Jonathan Schleifer <js@heap.zone>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFValue.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFValue_nonretainedObject: OFValue
{
	id _object;
}
@end

OF_ASSUME_NONNULL_END

Added src/OFValue_nonretainedObject.m version [e080df1e1c].

















































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
 *               2018
 *   Jonathan Schleifer <js@heap.zone>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFValue_nonretainedObject.h"
#import "OFMethodSignature.h"

#import "OFOutOfRangeException.h"

@implementation OFValue_nonretainedObject
@synthesize nonretainedObjectValue = _object;

- (instancetype)initWithNonretainedObject: (id)object
{
	self = [super init];

	_object = object;

	return self;
}

- (void)getValue: (void *)value
	    size: (size_t)size
{
	if (size != sizeof(_object))
		@throw [OFOutOfRangeException exception];

	memcpy(value, &_object, sizeof(_object));
}

- (void *)pointerValue
{
	return _object;
}
@end

Added src/OFValue_pointer.h version [e3ce2153e9].





























1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
 *               2018
 *   Jonathan Schleifer <js@heap.zone>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFValue.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFValue_pointer: OFValue
{
	void *_pointer;
}
@end

OF_ASSUME_NONNULL_END

Added src/OFValue_pointer.m version [46d3358a90].

















































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
 *               2018
 *   Jonathan Schleifer <js@heap.zone>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFValue_pointer.h"
#import "OFMethodSignature.h"

#import "OFOutOfRangeException.h"

@implementation OFValue_pointer
@synthesize pointerValue = _pointer;

- (instancetype)initWithPointer: (const void *)pointer
{
	self = [super init];

	_pointer = (void *)pointer;

	return self;
}

- (void)getValue: (void *)value
	    size: (size_t)size
{
	if (size != sizeof(_pointer))
		@throw [OFOutOfRangeException exception];

	memcpy(value, &_pointer, sizeof(_pointer));
}

- (id)nonretainedObjectValue
{
	return _pointer;
}
@end

Modified tests/OFValueTests.m from [c4c56eee46] to [1e0dc03201].

30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54


























55
56
57
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84







+


















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




@implementation TestsAppDelegate (OFValueTests)
- (void)valueTests
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	of_range_t range = of_range(1, 64), range2 = of_range(1, 64);
	OFValue *value;
	void *pointer = &value;

	TEST(@"+[valueWithBytes:objCType:]",
	    (value = [OFValue valueWithBytes: &range
				    objCType: @encode(of_range_t)]))

	TEST(@"-[objCType]", strcmp([value objCType], @encode(of_range_t)) == 0)

	range = of_range(OF_NOT_FOUND, 0);
	TEST(@"-[getValue:size:]",
	    R([value getValue: &range
			 size: sizeof(of_range_t)]) &&
	    memcmp(&range, &range2, sizeof(of_range_t)) == 0)

	EXPECT_EXCEPTION(@"-[getValue:size:] with wrong size throws",
	    OFOutOfRangeException,
	    [value getValue: &range
		       size: sizeof(of_range_t) - 1])

	TEST(@"+[valueWithPointer:]",
	    (value = [OFValue valueWithPointer: pointer]))

	TEST(@"-[pointerValue]",
	    [value pointerValue] == pointer &&
	    [[OFValue valueWithBytes: &pointer
			    objCType: @encode(void *)] pointerValue] == pointer)

	EXPECT_EXCEPTION(@"-[pointerValue] with wrong size throws",
	    OFOutOfRangeException,
	    [[OFValue valueWithBytes: "a"
			    objCType: @encode(char)] pointerValue])

	TEST(@"+[valueWithNonretainedObject:]",
	    (value = [OFValue valueWithNonretainedObject: pointer]))

	TEST(@"-[nonretainedObjectValue]",
	    [value nonretainedObjectValue] == pointer &&
	    [[OFValue valueWithBytes: &pointer
			    objCType: @encode(id)] pointerValue] == pointer)

	EXPECT_EXCEPTION(@"-[nonretainedObjectValue] with wrong size throws",
	    OFOutOfRangeException,
	    [[OFValue valueWithBytes: "a"
			    objCType: @encode(char)] nonretainedObjectValue])

	[pool drain];
}
@end