ObjFW  Check-in [c0a80a897d]

Overview
Comment:Merge trunk into branch "gamecontroller"
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | gamecontroller
Files: files | file ages | folders
SHA3-256: c0a80a897db56b5208b01e629bec48e1454bf9fffadab3107ffe7c7f7581fc83
User & Date: js on 2024-05-09 10:22:19
Other Links: branch diff | manifest | tags
Context
2024-05-09
12:57
OFGameController: Add support for Linux check-in: 6f20cdbd5c user: js tags: gamecontroller
10:22
Merge trunk into branch "gamecontroller" check-in: c0a80a897d user: js tags: gamecontroller
10:21
Use unsigned long for bit sets check-in: 96f946d7ad user: js tags: trunk
2024-05-05
23:07
OFGameController: Fix typos check-in: 3ef11175bc user: js tags: gamecontroller
Changes

Modified src/OFBitSetCharacterSet.h from [9f3314050d] to [ba3d4f6a9d].

19
20
21
22
23
24
25
26

27
28
29
30
31
19
20
21
22
23
24
25

26
27
28
29
30
31







-
+






#import "OFCharacterSet.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFBitSetCharacterSet: OFCharacterSet
{
	unsigned char *_bitset;
	unsigned long *_bitSet;
	size_t _size;
}
@end

OF_ASSUME_NONNULL_END

Modified src/OFBitSetCharacterSet.m from [b1982608cc] to [9db9ebbd67].

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
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







-
+






-
-
+
+

-
-
+
+
+
+




-
+













-
+






-
+


-
+


		void *pool = objc_autoreleasePoolPush();
		const OFUnichar *characters = string.characters;
		size_t length = string.length;

		for (size_t i = 0; i < length; i++) {
			OFUnichar c = characters[i];

			if (c / CHAR_BIT >= _size) {
			if (c / OF_ULONG_BIT >= _size) {
				size_t newSize;

				if (UINT32_MAX - c < 1)
					@throw [OFOutOfRangeException
					    exception];

				newSize = OFRoundUpToPowerOf2(CHAR_BIT, c + 1) /
				    CHAR_BIT;
				newSize = OFRoundUpToPowerOf2(OF_ULONG_BIT,
				    c + 1) / OF_ULONG_BIT;

				_bitset = OFResizeMemory(_bitset, newSize, 1);
				memset(_bitset + _size, '\0', newSize - _size);
				_bitSet = OFResizeMemory(_bitSet, newSize,
				    sizeof(unsigned long));
				memset(_bitSet + _size, '\0',
				    (newSize - _size) * sizeof(unsigned long));

				_size = newSize;
			}

			OFBitsetSet(_bitset, c);
			OFBitSetSet(_bitSet, c);
		}

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	OFFreeMemory(_bitset);
	OFFreeMemory(_bitSet);

	[super dealloc];
}

- (bool)characterIsMember: (OFUnichar)character
{
	if (character / CHAR_BIT >= _size)
	if (character / OF_ULONG_BIT >= _size)
		return false;

	return OFBitsetIsSet(_bitset, character);
	return OFBitSetIsSet(_bitSet, character);
}
@end

Modified src/OFSecureData.m from [5df33e3bf5] to [d0c4634748].

40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54







-
+







#import "OFOutOfRangeException.h"

#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)
static const size_t chunkSize = 16;

struct Page {
	struct Page *next, *previous;
	void *map;
	unsigned long *map;
	unsigned char *page;
};

# if defined(OF_HAVE_COMPILER_TLS)
static thread_local struct Page *firstPage = NULL;
static thread_local struct Page *lastPage = NULL;
static thread_local struct Page **preallocatedPages = NULL;
98
99
100
101
102
103
104
105
106


107
108
109
110
111
112
113
98
99
100
101
102
103
104


105
106
107
108
109
110
111
112
113







-
-
+
+







	munmap(pointer, numPages * pageSize);
}

static struct Page *
addPage(bool allowPreallocated)
{
	size_t pageSize = [OFSystemInfo pageSize];
	size_t mapSize = OFRoundUpToPowerOf2(CHAR_BIT, pageSize / chunkSize) /
	    CHAR_BIT;
	size_t mapSize = OFRoundUpToPowerOf2(OF_ULONG_BIT,
	    pageSize / chunkSize) / OF_ULONG_BIT;
	struct Page *page;
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	struct Page *lastPage;
# endif

	if (allowPreallocated) {
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
140
141
142
143
144
145
146

147
148
149
150
151
152
153
154







-
+








			return page;
		}
	}

	page = OFAllocMemory(1, sizeof(*page));
	@try {
		page->map = OFAllocZeroedMemory(1, mapSize);
		page->map = OFAllocZeroedMemory(mapSize, sizeof(unsigned long));
	} @catch (id e) {
		OFFreeMemory(page);
		@throw e;
	}
	@try {
		page->page = mapPages(1);
	} @catch (id e) {
182
183
184
185
186
187
188
189

190
191
192


193
194
195
196
197
198
199
182
183
184
185
186
187
188

189
190


191
192
193
194
195
196
197
198
199







-
+

-
-
+
+








	return page;
}

static void
removePageIfEmpty(struct Page *page)
{
	unsigned char *map = page->map;
	unsigned long *map = page->map;
	size_t pageSize = [OFSystemInfo pageSize];
	size_t mapSize = OFRoundUpToPowerOf2(CHAR_BIT, pageSize / chunkSize) /
	    CHAR_BIT;
	size_t mapSize = OFRoundUpToPowerOf2(OF_ULONG_BIT,
	    pageSize / chunkSize) / OF_ULONG_BIT;

	for (size_t i = 0; i < mapSize; i++)
		if (map[i] != 0)
			return;

	unmapPages(page->page, 1);
	OFFreeMemory(page->map);
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271







-
+











-
+



















-
+








	bytes = OFRoundUpToPowerOf2(chunkSize, bytes);
	chunks = chunksLeft = bytes / chunkSize;
	firstChunk = 0;
	pageSize = [OFSystemInfo pageSize];

	for (i = 0; i < pageSize / chunkSize; i++) {
		if (OFBitsetIsSet(page->map, i)) {
		if (OFBitSetIsSet(page->map, i)) {
			chunksLeft = chunks;
			firstChunk = i + 1;
			continue;
		}

		if (--chunksLeft == 0)
			break;
	}

	if (chunksLeft == 0) {
		for (size_t j = firstChunk; j < firstChunk + chunks; j++)
			OFBitsetSet(page->map, j);
			OFBitSetSet(page->map, j);

		return page->page + (chunkSize * firstChunk);
	}

	return NULL;
}

static void
freeMemory(struct Page *page, void *pointer, size_t bytes)
{
	size_t chunks, chunkIndex;

	bytes = OFRoundUpToPowerOf2(chunkSize, bytes);
	chunks = bytes / chunkSize;
	chunkIndex = ((uintptr_t)pointer - (uintptr_t)page->page) / chunkSize;

	OFZeroMemory(pointer, bytes);

	for (size_t i = 0; i < chunks; i++)
		OFBitsetClear(page->map, chunkIndex + i);
		OFBitSetClear(page->map, chunkIndex + i);
}
#endif

@implementation OFSecureData
@synthesize allowsSwappableMemory = _allowsSwappableMemory;

#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) && \

Modified src/OFStdIOStream.m from [2edbd17f16] to [4854e57444].

641
642
643
644
645
646
647



648

649
650
651
652
653
654
655
641
642
643
644
645
646
647
648
649
650

651
652
653
654
655
656
657
658







+
+
+
-
+







{
	if (!self.hasTerminal)
		return;

#ifdef OF_MSDOS
	gotoxy(column + 1, wherey());
#else
	if (column == 0)
		[self writeString: @"\r"];
	else
	[self writeFormat: @"\033[%uG", column + 1];
		[self writeFormat: @"\033[%uG", column + 1];
#endif
}

- (void)setCursorPosition: (OFPoint)position
{
	if (position.x < 0 || position.y < 0)
		@throw [OFInvalidArgumentException exception];

Modified src/macros.h from [e71e68e9ff] to [3c8f4714cc].

936
937
938
939
940
941
942


943
944

945
946

947
948
949
950

951
952

953
954
955
956

957
958

959
960
961
962
963
964
965
936
937
938
939
940
941
942
943
944
945

946
947

948
949
950
951

952
953

954
955
956
957

958
959

960
961
962
963
964
965
966
967







+
+

-
+

-
+



-
+

-
+



-
+

-
+







 * @param pow2 The power of 2 to round up to
 * @param value The value to round up to the specified power of two
 * @return The specified value rounded up to the specified power of two
 */
#define OFRoundUpToPowerOf2(pow2, value)	\
    (((value) + (pow2) - 1) & ~((pow2) - 1))

#define OF_ULONG_BIT (sizeof(unsigned long) * CHAR_BIT)

static OF_INLINE bool
OFBitsetIsSet(unsigned char *_Nonnull storage, size_t idx)
OFBitSetIsSet(unsigned long *_Nonnull storage, size_t idx)
{
	return storage[idx / CHAR_BIT] & (1u << (idx % CHAR_BIT));
	return storage[idx / OF_ULONG_BIT] & (1ul << (idx % OF_ULONG_BIT));
}

static OF_INLINE void
OFBitsetSet(unsigned char *_Nonnull storage, size_t idx)
OFBitSetSet(unsigned long *_Nonnull storage, size_t idx)
{
	storage[idx / CHAR_BIT] |= (1u << (idx % CHAR_BIT));
	storage[idx / OF_ULONG_BIT] |= (1ul << (idx % OF_ULONG_BIT));
}

static OF_INLINE void
OFBitsetClear(unsigned char *_Nonnull storage, size_t idx)
OFBitSetClear(unsigned long *_Nonnull storage, size_t idx)
{
	storage[idx / CHAR_BIT] &= ~(1u << (idx % CHAR_BIT));
	storage[idx / OF_ULONG_BIT] &= ~(1ul << (idx % OF_ULONG_BIT));
}

static OF_INLINE void
OFZeroMemory(void *_Nonnull buffer_, size_t length)
{
	volatile unsigned char *buffer = (volatile unsigned char *)buffer_;