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

#import "OFCharacterSet.h"

OF_ASSUME_NONNULL_BEGIN

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

OF_ASSUME_NONNULL_END







|





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

#import "OFCharacterSet.h"

OF_ASSUME_NONNULL_BEGIN

@interface OFBitSetCharacterSet: OFCharacterSet
{
	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
		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) {
				size_t newSize;

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

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

				_bitset = OFResizeMemory(_bitset, newSize, 1);

				memset(_bitset + _size, '\0', newSize - _size);


				_size = newSize;
			}

			OFBitsetSet(_bitset, c);
		}

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

	return self;
}

- (void)dealloc
{
	OFFreeMemory(_bitset);

	[super dealloc];
}

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

	return OFBitsetIsSet(_bitset, character);
}
@end







|






|
|

|
>
|
>




|













|






|


|


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 / OF_ULONG_BIT >= _size) {
				size_t newSize;

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

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

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

				_size = newSize;
			}

			OFBitSetSet(_bitSet, c);
		}

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

	return self;
}

- (void)dealloc
{
	OFFreeMemory(_bitSet);

	[super dealloc];
}

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

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







|







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







|
|







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

			return page;
		}
	}

	page = OFAllocMemory(1, sizeof(*page));
	@try {
		page->map = OFAllocZeroedMemory(1, mapSize);
	} @catch (id e) {
		OFFreeMemory(page);
		@throw e;
	}
	@try {
		page->page = mapPages(1);
	} @catch (id e) {







|







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

	return page;
}

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

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

	unmapPages(page->page, 1);
	OFFreeMemory(page->map);







|

|
|







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 long *map = page->map;
	size_t pageSize = [OFSystemInfo pageSize];
	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

	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)) {
			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);

		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);
}
#endif

@implementation OFSecureData
@synthesize allowsSwappableMemory = _allowsSwappableMemory;

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







|











|



















|







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)) {
			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);

		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);
}
#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
{
	if (!self.hasTerminal)
		return;

#ifdef OF_MSDOS
	gotoxy(column + 1, wherey());
#else



	[self writeFormat: @"\033[%uG", column + 1];
#endif
}

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







>
>
>
|







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];
#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
 * @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))



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

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

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

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








>
>

|

|



|

|



|

|







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 long *_Nonnull storage, size_t idx)
{
	return storage[idx / OF_ULONG_BIT] & (1ul << (idx % OF_ULONG_BIT));
}

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

static OF_INLINE void
OFBitSetClear(unsigned long *_Nonnull storage, size_t idx)
{
	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_;