1 | /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ |
2 | /* If you are missing that file, acquire a complete release at teeworlds.com. */ |
3 | |
4 | /* |
5 | Title: OS Abstraction |
6 | */ |
7 | |
8 | #ifndef BASE_SYSTEM_H |
9 | #define BASE_SYSTEM_H |
10 | |
11 | #include "detect.h" |
12 | #include "types.h" |
13 | |
14 | #ifndef __USE_GNU |
15 | #define __USE_GNU |
16 | #endif |
17 | |
18 | #include <chrono> |
19 | #include <cinttypes> |
20 | #include <cstdarg> |
21 | #include <cstdint> |
22 | #include <cstring> |
23 | #include <ctime> |
24 | #include <functional> |
25 | #include <mutex> |
26 | #include <optional> |
27 | #include <string> |
28 | |
29 | #ifdef __MINGW32__ |
30 | #undef PRId64 |
31 | #undef PRIu64 |
32 | #undef PRIX64 |
33 | #define PRId64 "I64d" |
34 | #define PRIu64 "I64u" |
35 | #define PRIX64 "I64X" |
36 | #define PRIzu "Iu" |
37 | #else |
38 | #define PRIzu "zu" |
39 | #endif |
40 | |
41 | #ifdef CONF_FAMILY_UNIX |
42 | #include <sys/un.h> |
43 | #endif |
44 | |
45 | #ifdef CONF_PLATFORM_LINUX |
46 | #include <netinet/in.h> |
47 | #include <sys/socket.h> |
48 | #endif |
49 | |
50 | #if __cplusplus >= 201703L |
51 | #define MAYBE_UNUSED [[maybe_unused]] |
52 | #elif defined(__GNUC__) |
53 | #define MAYBE_UNUSED __attribute__((unused)) |
54 | #else |
55 | #define MAYBE_UNUSED |
56 | #endif |
57 | |
58 | /** |
59 | * @defgroup Debug |
60 | * |
61 | * Utilities for debugging. |
62 | */ |
63 | |
64 | /** |
65 | * @ingroup Debug |
66 | * |
67 | * Breaks into the debugger based on a test. |
68 | * |
69 | * @param test Result of the test. |
70 | * @param msg Message that should be printed if the test fails. |
71 | * |
72 | * @remark Also works in release mode. |
73 | * |
74 | * @see dbg_break |
75 | */ |
76 | #define dbg_assert(test, msg) dbg_assert_imp(__FILE__, __LINE__, test, msg) |
77 | void dbg_assert_imp(const char *filename, int line, bool test, const char *msg); |
78 | |
79 | #ifdef __clang_analyzer__ |
80 | #include <cassert> |
81 | #undef dbg_assert |
82 | #define dbg_assert(test, msg) assert(test) |
83 | #endif |
84 | |
85 | #ifdef __GNUC__ |
86 | #define GNUC_ATTRIBUTE(x) __attribute__(x) |
87 | #else |
88 | #define GNUC_ATTRIBUTE(x) |
89 | #endif |
90 | |
91 | /** |
92 | * Checks whether the program is currently shutting down due to a failed |
93 | * assert. |
94 | * |
95 | * @ingroup Debug |
96 | * |
97 | * @return indication whether the program is currently shutting down due to a |
98 | * failed assert. |
99 | */ |
100 | bool dbg_assert_has_failed(); |
101 | |
102 | /** |
103 | * Breaks into the debugger. |
104 | * |
105 | * @ingroup Debug |
106 | * @remark Also works in release mode. |
107 | * |
108 | * @see dbg_assert |
109 | */ |
110 | #if defined(__cplusplus) |
111 | [[noreturn]] |
112 | #endif |
113 | void |
114 | dbg_break(); |
115 | |
116 | typedef std::function<void(const char *message)> DBG_ASSERT_HANDLER; |
117 | void dbg_assert_set_handler(DBG_ASSERT_HANDLER handler); |
118 | |
119 | /** |
120 | * Prints a debug message. |
121 | * |
122 | * @ingroup Debug |
123 | * |
124 | * @param sys A string that describes what system the message belongs to. |
125 | * @param fmt A printf styled format string. |
126 | * |
127 | * @remark Also works in release mode. |
128 | * |
129 | * @see dbg_assert |
130 | */ |
131 | void dbg_msg(const char *sys, const char *fmt, ...) |
132 | GNUC_ATTRIBUTE((format(printf, 2, 3))); |
133 | |
134 | /** |
135 | * @defgroup Memory |
136 | * Memory management utilities. |
137 | */ |
138 | |
139 | /** |
140 | * Copies a a memory block. |
141 | * |
142 | * @ingroup Memory |
143 | * |
144 | * @param dest Destination. |
145 | * @param source Source to copy. |
146 | * @param size Size of the block to copy. |
147 | * |
148 | * @remark This functions DOES NOT handle cases where the source and destination is overlapping. |
149 | * |
150 | * @see mem_move |
151 | */ |
152 | void mem_copy(void *dest, const void *source, size_t size); |
153 | |
154 | /** |
155 | * Copies a a memory block. |
156 | * |
157 | * @ingroup Memory |
158 | * |
159 | * @param dest Destination. |
160 | * @param source Source to copy. |
161 | * @param size Size of the block to copy. |
162 | * |
163 | * @remark This functions handles the cases where the source and destination is overlapping. |
164 | * |
165 | * @see mem_copy |
166 | */ |
167 | void mem_move(void *dest, const void *source, size_t size); |
168 | |
169 | /** |
170 | * Sets a complete memory block to 0. |
171 | * |
172 | * @ingroup Memory |
173 | * |
174 | * @param block Pointer to the block to zero out. |
175 | * @param size Size of the block. |
176 | */ |
177 | template<typename T> |
178 | inline void mem_zero(T *block, size_t size) |
179 | { |
180 | static_assert((std::is_trivially_constructible<T>::value && std::is_trivially_destructible<T>::value) || std::is_fundamental<T>::value); |
181 | memset(block, 0, size); |
182 | } |
183 | |
184 | /** |
185 | * Compares two blocks of memory |
186 | * |
187 | * @ingroup Memory |
188 | * |
189 | * @param a First block of data |
190 | * @param b Second block of data |
191 | * @param size Size of the data to compare |
192 | * |
193 | * @return < 0 - Block a is less than block b. |
194 | * @return 0 - Block a is equal to block b. |
195 | * @return > 0 - Block a is greater than block b. |
196 | */ |
197 | int mem_comp(const void *a, const void *b, size_t size); |
198 | |
199 | /** |
200 | * Checks whether a block of memory contains null bytes. |
201 | * |
202 | * @ingroup Memory |
203 | * |
204 | * @param block Pointer to the block to check for nulls. |
205 | * @param size Size of the block. |
206 | * |
207 | * @return true if the block has a null byte, false otherwise. |
208 | */ |
209 | bool mem_has_null(const void *block, size_t size); |
210 | |
211 | /** |
212 | * @defgroup File-IO |
213 | * |
214 | * I/O related operations. |
215 | */ |
216 | |
217 | /** |
218 | * @ingroup File-IO |
219 | */ |
220 | enum |
221 | { |
222 | IOFLAG_READ = 1, |
223 | IOFLAG_WRITE = 2, |
224 | IOFLAG_APPEND = 4, |
225 | IOFLAG_SKIP_BOM = 8, |
226 | |
227 | IOSEEK_START = 0, |
228 | IOSEEK_CUR = 1, |
229 | IOSEEK_END = 2, |
230 | }; |
231 | |
232 | /** |
233 | * Opens a file. |
234 | * |
235 | * @ingroup File-IO |
236 | * |
237 | * @param File to open. |
238 | * @param flags A set of IOFLAG flags. |
239 | * |
240 | * @sa IOFLAG_READ, IOFLAG_WRITE, IOFLAG_APPEND, IOFLAG_SKIP_BOM. |
241 | * |
242 | * @return A handle to the file on success and 0 on failure. |
243 | * |
244 | */ |
245 | IOHANDLE io_open(const char *filename, int flags); |
246 | |
247 | /** |
248 | * Reads data into a buffer from a file. |
249 | * |
250 | * @ingroup File-IO |
251 | * |
252 | * @param io Handle to the file to read data from. |
253 | * @param buffer Pointer to the buffer that will receive the data. |
254 | * @param size Number of bytes to read from the file. |
255 | * |
256 | * @return Number of bytes read. |
257 | * |
258 | */ |
259 | unsigned io_read(IOHANDLE io, void *buffer, unsigned size); |
260 | |
261 | /** |
262 | * Reads the rest of the file into a buffer. |
263 | * |
264 | * @ingroup File-IO |
265 | * |
266 | * @param io Handle to the file to read data from. |
267 | * @param result Receives the file's remaining contents. |
268 | * @param result_len Receives the file's remaining length. |
269 | * |
270 | * @remark Does NOT guarantee that there are no internal null bytes. |
271 | * @remark The result must be freed after it has been used. |
272 | */ |
273 | void io_read_all(IOHANDLE io, void **result, unsigned *result_len); |
274 | |
275 | /** |
276 | * Reads the rest of the file into a zero-terminated buffer with |
277 | * no internal null bytes. |
278 | * |
279 | * @ingroup File-IO |
280 | * |
281 | * @param io Handle to the file to read data from. |
282 | * |
283 | * @return The file's remaining contents or null on failure. |
284 | * |
285 | * @remark Guarantees that there are no internal null bytes. |
286 | * @remark Guarantees that result will contain zero-termination. |
287 | * @remark The result must be freed after it has been used. |
288 | */ |
289 | char *io_read_all_str(IOHANDLE io); |
290 | |
291 | /** |
292 | * Skips data in a file. |
293 | * |
294 | * @ingroup File-IO |
295 | * |
296 | * @param io Handle to the file. |
297 | * @param size Number of bytes to skip. |
298 | * |
299 | * @return 0 on success. |
300 | */ |
301 | int io_skip(IOHANDLE io, int size); |
302 | |
303 | /** |
304 | * Writes data from a buffer to file. |
305 | * |
306 | * @ingroup File-IO |
307 | * |
308 | * @param io Handle to the file. |
309 | * @param buffer Pointer to the data that should be written. |
310 | * @param size Number of bytes to write. |
311 | * |
312 | * @return Number of bytes written. |
313 | */ |
314 | unsigned io_write(IOHANDLE io, const void *buffer, unsigned size); |
315 | |
316 | /** |
317 | * Writes a platform dependent newline to file. |
318 | * |
319 | * @ingroup File-IO |
320 | * |
321 | * @param io Handle to the file. |
322 | * |
323 | * @return true on success, false on failure. |
324 | */ |
325 | bool io_write_newline(IOHANDLE io); |
326 | |
327 | /** |
328 | * Seeks to a specified offset in the file. |
329 | * |
330 | * @ingroup File-IO |
331 | * |
332 | * @param io Handle to the file. |
333 | * @param offset Offset from pos to stop. |
334 | * @param origin Position to start searching from. |
335 | * |
336 | * @return 0 on success. |
337 | */ |
338 | int io_seek(IOHANDLE io, int offset, int origin); |
339 | |
340 | /** |
341 | * Gets the current position in the file. |
342 | * |
343 | * @ingroup File-IO |
344 | * |
345 | * @param io Handle to the file. |
346 | * |
347 | * @return The current position. @c -1L if an error occurred. |
348 | */ |
349 | long int io_tell(IOHANDLE io); |
350 | |
351 | /** |
352 | * Gets the total length of the file. Resetting cursor to the beginning |
353 | * |
354 | * @ingroup File-IO |
355 | * |
356 | * @param io Handle to the file. |
357 | * |
358 | * @return The total size. @c -1L if an error occurred. |
359 | */ |
360 | long int io_length(IOHANDLE io); |
361 | |
362 | /** |
363 | * Closes a file. |
364 | * |
365 | * @ingroup File-IO |
366 | * |
367 | * @param io Handle to the file. |
368 | * |
369 | * @return 0 on success. |
370 | */ |
371 | int io_close(IOHANDLE io); |
372 | |
373 | /** |
374 | * Empties all buffers and writes all pending data. |
375 | * |
376 | * @ingroup File-IO |
377 | * |
378 | * @param io Handle to the file. |
379 | * |
380 | * @return 0 on success. |
381 | */ |
382 | int io_flush(IOHANDLE io); |
383 | |
384 | /** |
385 | * Synchronize file changes to disk. |
386 | * |
387 | * @ingroup File-IO |
388 | * |
389 | * @param io Handle to the file. |
390 | * |
391 | * @return 0 on success. |
392 | */ |
393 | int io_sync(IOHANDLE io); |
394 | |
395 | /** |
396 | * Checks whether an error occurred during I/O with the file. |
397 | * |
398 | * @ingroup File-IO |
399 | * |
400 | * @param io Handle to the file. |
401 | * |
402 | * @return nonzero on error, 0 otherwise. |
403 | */ |
404 | int io_error(IOHANDLE io); |
405 | |
406 | /** |
407 | * @ingroup File-IO |
408 | * @return An <IOHANDLE> to the standard input. |
409 | */ |
410 | IOHANDLE io_stdin(); |
411 | |
412 | /** |
413 | * @ingroup File-IO |
414 | * @return An <IOHANDLE> to the standard output. |
415 | */ |
416 | IOHANDLE io_stdout(); |
417 | |
418 | /** |
419 | * @ingroup File-IO |
420 | * @return An <IOHANDLE> to the standard error. |
421 | */ |
422 | IOHANDLE io_stderr(); |
423 | |
424 | /** |
425 | * @ingroup File-IO |
426 | * @return An <IOHANDLE> to the current executable. |
427 | */ |
428 | IOHANDLE io_current_exe(); |
429 | |
430 | typedef struct ASYNCIO ASYNCIO; |
431 | |
432 | /** |
433 | * Wraps a @link IOHANDLE @endlink for asynchronous writing. |
434 | * |
435 | * @ingroup File-IO |
436 | * |
437 | * @param io Handle to the file. |
438 | * |
439 | * @return The handle for asynchronous writing. |
440 | * |
441 | */ |
442 | ASYNCIO *aio_new(IOHANDLE io); |
443 | |
444 | /** |
445 | * Locks the ASYNCIO structure so it can't be written into by |
446 | * other threads. |
447 | * |
448 | * @ingroup File-IO |
449 | * |
450 | * @param aio Handle to the file. |
451 | */ |
452 | void aio_lock(ASYNCIO *aio); |
453 | |
454 | /** |
455 | * Unlocks the ASYNCIO structure after finishing the contiguous |
456 | * write. |
457 | * |
458 | * @ingroup File-IO |
459 | * |
460 | * @param aio Handle to the file. |
461 | */ |
462 | void aio_unlock(ASYNCIO *aio); |
463 | |
464 | /** |
465 | * Queues a chunk of data for writing. |
466 | * |
467 | * @ingroup File-IO |
468 | * |
469 | * @param aio Handle to the file. |
470 | * @param buffer Pointer to the data that should be written. |
471 | * @param size Number of bytes to write. |
472 | */ |
473 | void aio_write(ASYNCIO *aio, const void *buffer, unsigned size); |
474 | |
475 | /** |
476 | * Queues a newline for writing. |
477 | * |
478 | * @ingroup File-IO |
479 | * |
480 | * @param aio Handle to the file. |
481 | * |
482 | */ |
483 | void aio_write_newline(ASYNCIO *aio); |
484 | |
485 | /** |
486 | * Queues a chunk of data for writing. The ASYNCIO struct must be |
487 | * locked using @link aio_lock @endlink first. |
488 | * |
489 | * @ingroup File-IO |
490 | * |
491 | * @param aio Handle to the file. |
492 | * @param buffer Pointer to the data that should be written. |
493 | * @param size Number of bytes to write. |
494 | * |
495 | */ |
496 | void aio_write_unlocked(ASYNCIO *aio, const void *buffer, unsigned size); |
497 | |
498 | /** |
499 | * Queues a newline for writing. The ASYNCIO struct must be locked |
500 | * using @link aio_lock @endlink first. |
501 | * |
502 | * @ingroup File-IO |
503 | * |
504 | * @param aio Handle to the file. |
505 | * |
506 | */ |
507 | void aio_write_newline_unlocked(ASYNCIO *aio); |
508 | |
509 | /** |
510 | * Checks whether errors have occurred during the asynchronous |
511 | * writing. |
512 | * |
513 | * Call this function regularly to see if there are errors. Call |
514 | * this function after <aio_wait> to see if the process of writing |
515 | * to the file succeeded. |
516 | * |
517 | * @ingroup File-IO |
518 | * |
519 | * @param aio Handle to the file. |
520 | * |
521 | * @eturn 0 if no error occurred, and nonzero on error. |
522 | * |
523 | */ |
524 | int aio_error(ASYNCIO *aio); |
525 | |
526 | /** |
527 | * Queues file closing. |
528 | * |
529 | * @ingroup File-IO |
530 | * |
531 | * @param aio Handle to the file. |
532 | * |
533 | */ |
534 | void aio_close(ASYNCIO *aio); |
535 | |
536 | /** |
537 | * Wait for the asynchronous operations to complete. |
538 | * |
539 | * @ingroup File-IO |
540 | * |
541 | * @param aio Handle to the file. |
542 | * |
543 | */ |
544 | void aio_wait(ASYNCIO *aio); |
545 | |
546 | /** |
547 | * Frees the resources associated to the asynchronous file handle. |
548 | * |
549 | * @ingroup File-IO |
550 | * |
551 | * @param aio Handle to the file. |
552 | * |
553 | */ |
554 | void aio_free(ASYNCIO *aio); |
555 | |
556 | /** |
557 | * @defgroup Threads |
558 | * Threading related functions. |
559 | * |
560 | * @see Locks |
561 | * @see Semaphore |
562 | */ |
563 | |
564 | /** |
565 | * Creates a new thread. |
566 | * |
567 | * @ingroup Threads |
568 | * |
569 | * @param threadfunc Entry point for the new thread. |
570 | * @param user Pointer to pass to the thread. |
571 | * @param name Name describing the use of the thread. |
572 | * |
573 | * @return Handle for the new thread. |
574 | */ |
575 | void *thread_init(void (*threadfunc)(void *), void *user, const char *name); |
576 | |
577 | /** |
578 | * Waits for a thread to be done or destroyed. |
579 | * |
580 | * @ingroup Threads |
581 | * |
582 | * @param thread Thread to wait for. |
583 | */ |
584 | void thread_wait(void *thread); |
585 | |
586 | /** |
587 | * Yield the current thread's execution slice. |
588 | * |
589 | * @ingroup Threads |
590 | */ |
591 | void thread_yield(); |
592 | |
593 | /** |
594 | * Puts the thread in the detached state, guaranteeing that |
595 | * resources of the thread will be freed immediately when the |
596 | * thread terminates. |
597 | * |
598 | * @ingroup Threads |
599 | * |
600 | * @param thread Thread to detach. |
601 | */ |
602 | void thread_detach(void *thread); |
603 | |
604 | /** |
605 | * Creates a new thread and detaches it. |
606 | * |
607 | * @ingroup Threads |
608 | * |
609 | * @param threadfunc Entry point for the new thread. |
610 | * @param user Pointer to pass to the thread. |
611 | * @param name Name describing the use of the thread. |
612 | */ |
613 | void thread_init_and_detach(void (*threadfunc)(void *), void *user, const char *name); |
614 | |
615 | /** |
616 | * @defgroup Semaphore |
617 | * @see Threads |
618 | */ |
619 | |
620 | #if defined(CONF_FAMILY_WINDOWS) |
621 | typedef void *SEMAPHORE; |
622 | #elif defined(CONF_PLATFORM_MACOS) |
623 | #include <semaphore.h> |
624 | typedef sem_t *SEMAPHORE; |
625 | #elif defined(CONF_FAMILY_UNIX) |
626 | #include <semaphore.h> |
627 | typedef sem_t SEMAPHORE; |
628 | #else |
629 | #error not implemented on this platform |
630 | #endif |
631 | |
632 | /** |
633 | * @ingroup Semaphore |
634 | */ |
635 | void sphore_init(SEMAPHORE *sem); |
636 | /** |
637 | * @ingroup Semaphore |
638 | */ |
639 | void sphore_wait(SEMAPHORE *sem); |
640 | /** |
641 | * @ingroup Semaphore |
642 | */ |
643 | void sphore_signal(SEMAPHORE *sem); |
644 | /** |
645 | * @ingroup Semaphore |
646 | */ |
647 | void sphore_destroy(SEMAPHORE *sem); |
648 | |
649 | /** |
650 | * @defgroup Time |
651 | * |
652 | * Time utilities. |
653 | */ |
654 | |
655 | /** |
656 | * @ingroup Time |
657 | */ |
658 | void set_new_tick(); |
659 | |
660 | /** |
661 | * Fetches a sample from a high resolution timer. |
662 | * |
663 | * @ingroup Time |
664 | * |
665 | * @return Current value of the timer. |
666 | * |
667 | * @remark To know how fast the timer is ticking, see @link time_freq @endlink. |
668 | * |
669 | * @see time_freq |
670 | */ |
671 | int64_t time_get_impl(); |
672 | |
673 | /** |
674 | * Fetches a sample from a high resolution timer. |
675 | * |
676 | * @ingroup Time |
677 | * |
678 | * @return Current value of the timer. |
679 | * |
680 | * @remark To know how fast the timer is ticking, see @link time_freq @endlink. |
681 | * @remark Uses @link time_get_impl @endlink to fetch the sample. |
682 | * |
683 | * @see time_freq time_get_impl |
684 | */ |
685 | int64_t time_get(); |
686 | |
687 | /** |
688 | * @ingroup Time |
689 | * |
690 | * @return The frequency of the high resolution timer. |
691 | */ |
692 | int64_t time_freq(); |
693 | |
694 | /** |
695 | * Retrieves the current time as a UNIX timestamp |
696 | * |
697 | * @ingroup Time |
698 | * |
699 | * @return The time as a UNIX timestamp |
700 | */ |
701 | int64_t time_timestamp(); |
702 | |
703 | /** |
704 | * Retrieves the hours since midnight (0..23) |
705 | * |
706 | * @ingroup Time |
707 | * |
708 | * @return The current hour of the day |
709 | */ |
710 | int time_houroftheday(); |
711 | |
712 | /** |
713 | * @ingroup Time |
714 | */ |
715 | enum ETimeSeason |
716 | { |
717 | SEASON_SPRING = 0, |
718 | SEASON_SUMMER, |
719 | SEASON_AUTUMN, |
720 | SEASON_WINTER, |
721 | SEASON_EASTER, |
722 | SEASON_HALLOWEEN, |
723 | SEASON_XMAS, |
724 | SEASON_NEWYEAR |
725 | }; |
726 | |
727 | /** |
728 | * Retrieves the current season of the year. |
729 | * |
730 | * @ingroup Time |
731 | * |
732 | * @return One of the SEASON_* enum literals |
733 | * |
734 | * @see SEASON_SPRING |
735 | */ |
736 | ETimeSeason time_season(); |
737 | |
738 | /** |
739 | * @defgroup Network-General |
740 | */ |
741 | |
742 | extern const NETADDR NETADDR_ZEROED; |
743 | |
744 | /** |
745 | * @ingroup Network-General |
746 | */ |
747 | |
748 | #ifdef CONF_FAMILY_UNIX |
749 | /** |
750 | * @ingroup Network-General |
751 | */ |
752 | typedef int UNIXSOCKET; |
753 | /** |
754 | * @ingroup Network-General |
755 | */ |
756 | typedef struct sockaddr_un UNIXSOCKETADDR; |
757 | #endif |
758 | |
759 | /** |
760 | * Initiates network functionality. |
761 | * |
762 | * @ingroup Network-General |
763 | * |
764 | * @remark You must call this function before using any other network functions. |
765 | */ |
766 | void net_init(); |
767 | |
768 | /* |
769 | Function: net_host_lookup |
770 | Does a hostname lookup by name and fills out the passed |
771 | NETADDR struct with the received details. |
772 | |
773 | Returns: |
774 | 0 on success. |
775 | */ |
776 | int net_host_lookup(const char *hostname, NETADDR *addr, int types); |
777 | |
778 | /** |
779 | * Compares two network addresses. |
780 | * |
781 | * @ingroup Network-General |
782 | * |
783 | * @param a Address to compare |
784 | * @param b Address to compare to. |
785 | * |
786 | * @return `< 0` - Address a is less than address b |
787 | * @return `0` - Address a is equal to address b |
788 | * @return `> 0` - Address a is greater than address b |
789 | */ |
790 | int net_addr_comp(const NETADDR *a, const NETADDR *b); |
791 | |
792 | /** |
793 | * Compares two network addresses ignoring port. |
794 | * |
795 | * @ingroup Network-General |
796 | * |
797 | * @param a Address to compare |
798 | * @param b Address to compare to. |
799 | * |
800 | * @return `< 0` - Address a is less than address b |
801 | * @return `0` - Address a is equal to address b |
802 | * @return `> 0` - Address a is greater than address b |
803 | */ |
804 | int net_addr_comp_noport(const NETADDR *a, const NETADDR *b); |
805 | |
806 | /** |
807 | * Turns a network address into a representative string. |
808 | * |
809 | * @ingroup Network-General |
810 | * |
811 | * @param addr Address to turn into a string. |
812 | * @param string Buffer to fill with the string. |
813 | * @param max_length Maximum size of the string. |
814 | * @param add_port add port to string or not |
815 | * |
816 | * @remark The string will always be zero terminated |
817 | */ |
818 | void net_addr_str(const NETADDR *addr, char *string, int max_length, int add_port); |
819 | |
820 | /** |
821 | * Turns url string into a network address struct. |
822 | * The url format is tw-0.6+udp://{ipaddr}[:{port}] |
823 | * ipaddr: can be ipv4 or ipv6 |
824 | * port: is a optional internet protocol port |
825 | * |
826 | * This format is used for parsing the master server, be careful before changing it. |
827 | * |
828 | * Examples: |
829 | * tw-0.6+udp://127.0.0.1 |
830 | * tw-0.6+udp://127.0.0.1:8303 |
831 | * |
832 | * @param addr Address to fill in. |
833 | * @param string String to parse. |
834 | * @param host_buf Pointer to a buffer to write the host to |
835 | * It will include the port if one is included in the url |
836 | * It can also be set to NULL then it will be ignored |
837 | * @param host_buf_size Size of the host buffer or 0 if no host_buf pointer is given |
838 | * |
839 | * @return 0 on success, |
840 | * positive if the input wasn't a valid DDNet URL, |
841 | * negative if the input is a valid DDNet URL but the host part was not a valid IPv4/IPv6 address |
842 | */ |
843 | int net_addr_from_url(NETADDR *addr, const char *string, char *host_buf, size_t host_buf_size); |
844 | |
845 | /** |
846 | * Turns string into a network address. |
847 | * |
848 | * @param addr Address to fill in. |
849 | * @param string String to parse. |
850 | * |
851 | * @return 0 on success |
852 | */ |
853 | int net_addr_from_str(NETADDR *addr, const char *string); |
854 | |
855 | /** |
856 | * @defgroup Network-UDP |
857 | * @ingroup Network-General |
858 | */ |
859 | |
860 | /* |
861 | Function: net_socket_type |
862 | Determine a socket's type. |
863 | |
864 | Parameters: |
865 | sock - Socket whose type should be determined. |
866 | |
867 | Returns: |
868 | The socket type, a bitset of `NETTYPE_IPV4`, `NETTYPE_IPV6` and |
869 | `NETTYPE_WEBSOCKET_IPV4`. |
870 | */ |
871 | int net_socket_type(NETSOCKET sock); |
872 | |
873 | /* |
874 | Function: net_udp_create |
875 | Creates a UDP socket and binds it to a port. |
876 | |
877 | Parameters: |
878 | bindaddr - Address to bind the socket to. |
879 | |
880 | Returns: |
881 | On success it returns an handle to the socket. On failure it |
882 | returns NETSOCKET_INVALID. |
883 | */ |
884 | NETSOCKET net_udp_create(NETADDR bindaddr); |
885 | |
886 | /** |
887 | * Sends a packet over an UDP socket. |
888 | * |
889 | * @ingroup Network-UDP |
890 | * |
891 | * @param sock Socket to use. |
892 | * @param addr Where to send the packet. |
893 | * @param data Pointer to the packet data to send. |
894 | * @param size Size of the packet. |
895 | * |
896 | * @return On success it returns the number of bytes sent. Returns -1 |
897 | * on error. |
898 | */ |
899 | int net_udp_send(NETSOCKET sock, const NETADDR *addr, const void *data, int size); |
900 | |
901 | /* |
902 | Function: net_udp_recv |
903 | Receives a packet over an UDP socket. |
904 | |
905 | Parameters: |
906 | sock - Socket to use. |
907 | addr - Pointer to an NETADDR that will receive the address. |
908 | data - Received data. Will be invalidated when this function is |
909 | called again. |
910 | |
911 | Returns: |
912 | On success it returns the number of bytes received. Returns -1 |
913 | on error. |
914 | */ |
915 | int net_udp_recv(NETSOCKET sock, NETADDR *addr, unsigned char **data); |
916 | |
917 | /** |
918 | * Closes an UDP socket. |
919 | * |
920 | * @ingroup Network-UDP |
921 | * |
922 | * @param sock Socket to close. |
923 | * |
924 | * @return 0 on success. -1 on error. |
925 | */ |
926 | int net_udp_close(NETSOCKET sock); |
927 | |
928 | /** |
929 | * @defgroup Network-TCP |
930 | * @ingroup Network-General |
931 | */ |
932 | |
933 | /** |
934 | * Creates a TCP socket. |
935 | * |
936 | * @ingroup Network-TCP |
937 | * |
938 | * @param bindaddr Address to bind the socket to. |
939 | * |
940 | * @return On success it returns an handle to the socket. On failure it returns NETSOCKET_INVALID. |
941 | */ |
942 | NETSOCKET net_tcp_create(NETADDR bindaddr); |
943 | |
944 | /** |
945 | * Makes the socket start listening for new connections. |
946 | * |
947 | * @ingroup Network-TCP |
948 | * |
949 | * @param sock Socket to start listen to. |
950 | * @param backlog Size of the queue of incoming connections to keep. |
951 | * |
952 | * @return 0 on success. |
953 | */ |
954 | int net_tcp_listen(NETSOCKET sock, int backlog); |
955 | |
956 | /** |
957 | * Polls a listning socket for a new connection. |
958 | * |
959 | * @ingroup Network-TCP |
960 | * |
961 | * @param sock - Listning socket to poll. |
962 | * @param new_sock - Pointer to a socket to fill in with the new socket. |
963 | * @param addr - Pointer to an address that will be filled in the remote address (optional, can be NULL). |
964 | * |
965 | * @return A non-negative integer on success. Negative integer on failure. |
966 | */ |
967 | int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *addr); |
968 | |
969 | /** |
970 | * Connects one socket to another. |
971 | * |
972 | * @ingroup Network-TCP |
973 | * |
974 | * @param sock Socket to connect. |
975 | * @param addr Address to connect to. |
976 | * |
977 | * @return 0 on success. |
978 | * |
979 | */ |
980 | int net_tcp_connect(NETSOCKET sock, const NETADDR *addr); |
981 | |
982 | /** |
983 | * Sends data to a TCP stream. |
984 | * |
985 | * @ingroup Network-TCP |
986 | * |
987 | * @param sock Socket to send data to. |
988 | * @param data Pointer to the data to send. |
989 | * @param size Size of the data to send. |
990 | * |
991 | * @return Number of bytes sent. Negative value on failure. |
992 | */ |
993 | int net_tcp_send(NETSOCKET sock, const void *data, int size); |
994 | |
995 | /** |
996 | * Recvives data from a TCP stream. |
997 | * |
998 | * @ingroup Network-TCP |
999 | * |
1000 | * @param sock Socket to recvive data from. |
1001 | * @param data Pointer to a buffer to write the data to |
1002 | * @param max_size Maximum of data to write to the buffer. |
1003 | * |
1004 | * @return Number of bytes recvived. Negative value on failure. When in |
1005 | * non-blocking mode, it returns 0 when there is no more data to |
1006 | * be fetched. |
1007 | */ |
1008 | int net_tcp_recv(NETSOCKET sock, void *data, int maxsize); |
1009 | |
1010 | /** |
1011 | * Closes a TCP socket. |
1012 | * |
1013 | * @ingroup Network-TCP |
1014 | * |
1015 | * @param sock Socket to close. |
1016 | * |
1017 | * @return 0 on success. Negative value on failure. |
1018 | */ |
1019 | int net_tcp_close(NETSOCKET sock); |
1020 | |
1021 | #if defined(CONF_FAMILY_UNIX) |
1022 | /** |
1023 | * @defgroup Network-Unix-Sockets |
1024 | * @ingroup Network-General |
1025 | */ |
1026 | |
1027 | /** |
1028 | * Creates an unnamed unix datagram socket. |
1029 | * |
1030 | * @ingroup Network-Unix-Sockets |
1031 | * |
1032 | * @return On success it returns a handle to the socket. On failure it returns -1. |
1033 | */ |
1034 | UNIXSOCKET net_unix_create_unnamed(); |
1035 | |
1036 | /** |
1037 | * Sends data to a Unix socket. |
1038 | * |
1039 | * @ingroup Network-Unix-Sockets |
1040 | * |
1041 | * @param sock Socket to use. |
1042 | * @param addr Where to send the packet. |
1043 | * @param data Pointer to the packet data to send. |
1044 | * @param size Size of the packet. |
1045 | * |
1046 | * @return Number of bytes sent. Negative value on failure. |
1047 | */ |
1048 | int net_unix_send(UNIXSOCKET sock, UNIXSOCKETADDR *addr, void *data, int size); |
1049 | |
1050 | /** |
1051 | * Sets the unixsocketaddress for a path to a socket file. |
1052 | * |
1053 | * @ingroup Network-Unix-Sockets |
1054 | * |
1055 | * @param addr Pointer to the addressstruct to fill. |
1056 | * @param path Path to the (named) unix socket. |
1057 | */ |
1058 | void net_unix_set_addr(UNIXSOCKETADDR *addr, const char *path); |
1059 | |
1060 | /** |
1061 | * Closes a Unix socket. |
1062 | * |
1063 | * @ingroup Network-Unix-Sockets |
1064 | * |
1065 | * @param sock Socket to close. |
1066 | */ |
1067 | void net_unix_close(UNIXSOCKET sock); |
1068 | |
1069 | #elif defined(CONF_FAMILY_WINDOWS) |
1070 | |
1071 | /** |
1072 | * Formats a Windows error code as a human-readable string. |
1073 | * |
1074 | * @param error The Windows error code. |
1075 | * |
1076 | * @return A new std::string representing the error code. |
1077 | */ |
1078 | std::string windows_format_system_message(unsigned long error); |
1079 | |
1080 | #endif |
1081 | |
1082 | /** |
1083 | * @defgroup Strings |
1084 | * |
1085 | * String related functions. |
1086 | */ |
1087 | |
1088 | /** |
1089 | * Appends a string to another. |
1090 | * |
1091 | * @ingroup Strings |
1092 | * |
1093 | * @param dst Pointer to a buffer that contains a string. |
1094 | * @param src String to append. |
1095 | * @param dst_size Size of the buffer of the dst string. |
1096 | * |
1097 | * @remark The strings are treated as zero-terminated strings. |
1098 | * @remark Guarantees that dst string will contain zero-termination. |
1099 | */ |
1100 | void str_append(char *dst, const char *src, int dst_size); |
1101 | |
1102 | /** |
1103 | * Appends a string to a fixed-size array of chars. |
1104 | * |
1105 | * @ingroup Strings |
1106 | * |
1107 | * @param dst Array that shall receive the string. |
1108 | * @param src String to append. |
1109 | * |
1110 | * @remark The strings are treated as zero-terminated strings. |
1111 | * @remark Guarantees that dst string will contain zero-termination. |
1112 | */ |
1113 | template<int N> |
1114 | void str_append(char (&dst)[N], const char *src) |
1115 | { |
1116 | str_append(dst, src, N); |
1117 | } |
1118 | |
1119 | /** |
1120 | * Copies a string to another. |
1121 | * |
1122 | * @ingroup Strings |
1123 | * |
1124 | * @param dst Pointer to a buffer that shall receive the string. |
1125 | * @param src String to be copied. |
1126 | * @param dst_size Size of the buffer dst. |
1127 | * |
1128 | * @return Length of written string, even if it has been truncated |
1129 | * |
1130 | * @remark The strings are treated as zero-terminated strings. |
1131 | * @remark Guarantees that dst string will contain zero-termination. |
1132 | */ |
1133 | int str_copy(char *dst, const char *src, int dst_size); |
1134 | |
1135 | /** |
1136 | * Copies a string to a fixed-size array of chars. |
1137 | * |
1138 | * @ingroup Strings |
1139 | * |
1140 | * @param dst Array that shall receive the string. |
1141 | * @param src String to be copied. |
1142 | * |
1143 | * @remark The strings are treated as zero-terminated strings. |
1144 | * @remark Guarantees that dst string will contain zero-termination. |
1145 | */ |
1146 | template<int N> |
1147 | void str_copy(char (&dst)[N], const char *src) |
1148 | { |
1149 | str_copy(dst, src, N); |
1150 | } |
1151 | |
1152 | /** |
1153 | * Truncates a utf8 encoded string to a given length. |
1154 | * |
1155 | * @ingroup Strings |
1156 | * |
1157 | * @param dst Pointer to a buffer that shall receive the string. |
1158 | * @param dst_size Size of the buffer dst. |
1159 | * @param str String to be truncated. |
1160 | * @param truncation_len Maximum codepoints in the returned string. |
1161 | * |
1162 | * @remark The strings are treated as utf8-encoded zero-terminated strings. |
1163 | * @remark Guarantees that dst string will contain zero-termination. |
1164 | */ |
1165 | void str_utf8_truncate(char *dst, int dst_size, const char *src, int truncation_len); |
1166 | |
1167 | /** |
1168 | * Truncates a string to a given length. |
1169 | * |
1170 | * @ingroup Strings |
1171 | * |
1172 | * @param dst Pointer to a buffer that shall receive the string. |
1173 | * @param dst_size Size of the buffer dst. |
1174 | * @param src String to be truncated. |
1175 | * @param truncation_len Maximum length of the returned string (not |
1176 | * counting the zero termination). |
1177 | * |
1178 | * @remark The strings are treated as zero-terminated strings. |
1179 | * @remark Guarantees that dst string will contain zero-termination. |
1180 | */ |
1181 | void str_truncate(char *dst, int dst_size, const char *src, int truncation_len); |
1182 | |
1183 | /** |
1184 | * Returns the length of a zero terminated string. |
1185 | * |
1186 | * @ingroup Strings |
1187 | * |
1188 | * @param str Pointer to the string. |
1189 | * |
1190 | * @return Length of string in bytes excluding the zero termination. |
1191 | */ |
1192 | int str_length(const char *str); |
1193 | |
1194 | /** |
1195 | * Performs printf formatting into a buffer. |
1196 | * |
1197 | * @ingroup Strings |
1198 | * |
1199 | * @param buffer Pointer to the buffer to receive the formatted string. |
1200 | * @param buffer_size Size of the buffer. |
1201 | * @param format printf formatting string. |
1202 | * @param args The variable argument list. |
1203 | * |
1204 | * @return Length of written string, even if it has been truncated. |
1205 | * |
1206 | * @remark See the C manual for syntax for the printf formatting string. |
1207 | * @remark The strings are treated as zero-terminated strings. |
1208 | * @remark Guarantees that buffer string will contain zero-termination. |
1209 | */ |
1210 | int str_format_v(char *buffer, int buffer_size, const char *format, va_list args) |
1211 | GNUC_ATTRIBUTE((format(printf, 3, 0))); |
1212 | |
1213 | /** |
1214 | * Performs printf formatting into a buffer. |
1215 | * |
1216 | * @ingroup Strings |
1217 | * |
1218 | * @param buffer Pointer to the buffer to receive the formatted string. |
1219 | * @param buffer_size Size of the buffer. |
1220 | * @param format printf formatting string. |
1221 | * @param ... Parameters for the formatting. |
1222 | * |
1223 | * @return Length of written string, even if it has been truncated. |
1224 | * |
1225 | * @remark See the C manual for syntax for the printf formatting string. |
1226 | * @remark The strings are treated as zero-terminated strings. |
1227 | * @remark Guarantees that buffer string will contain zero-termination. |
1228 | */ |
1229 | int str_format(char *buffer, int buffer_size, const char *format, ...) |
1230 | GNUC_ATTRIBUTE((format(printf, 3, 4))); |
1231 | |
1232 | #if !defined(CONF_DEBUG) |
1233 | int str_format_int(char *buffer, size_t buffer_size, int value); |
1234 | |
1235 | template<typename... Args> |
1236 | int str_format_opt(char *buffer, int buffer_size, const char *format, Args... args) |
1237 | { |
1238 | return str_format(buffer, buffer_size, format, args...); |
1239 | } |
1240 | |
1241 | template<> |
1242 | inline int str_format_opt(char *buffer, int buffer_size, const char *format, int val) |
1243 | { |
1244 | if(strcmp(format, "%d" ) == 0) |
1245 | { |
1246 | return str_format_int(buffer, buffer_size, val); |
1247 | } |
1248 | else |
1249 | { |
1250 | return str_format(buffer, buffer_size, format, val); |
1251 | } |
1252 | } |
1253 | |
1254 | #define str_format str_format_opt |
1255 | #endif |
1256 | |
1257 | /** |
1258 | * Trims specific number of words at the start of a string. |
1259 | * |
1260 | * @ingroup Strings |
1261 | * |
1262 | * @param str String to trim the words from. |
1263 | * @param words Count of words to trim. |
1264 | * |
1265 | * @return Trimmed string |
1266 | * |
1267 | * @remark The strings are treated as zero-terminated strings. |
1268 | * @remark Leading whitespace is always trimmed. |
1269 | */ |
1270 | const char *str_trim_words(const char *str, int words); |
1271 | |
1272 | /** |
1273 | * Check whether string has ASCII control characters. |
1274 | * |
1275 | * @ingroup Strings |
1276 | * |
1277 | * @param str String to check. |
1278 | * |
1279 | * @return Whether the string has ASCII control characters. |
1280 | * |
1281 | * @remark The strings are treated as zero-terminated strings. |
1282 | */ |
1283 | bool str_has_cc(const char *str); |
1284 | |
1285 | /** |
1286 | * Replaces all characters below 32 with whitespace. |
1287 | * |
1288 | * @ingroup Strings |
1289 | * |
1290 | * @param str String to sanitize. |
1291 | * |
1292 | * @remark The strings are treated as zero-terminated strings. |
1293 | */ |
1294 | void str_sanitize_cc(char *str); |
1295 | |
1296 | /** |
1297 | * Replaces all characters below 32 with whitespace with |
1298 | * exception to \t, \n and \r. |
1299 | * |
1300 | * @ingroup Strings |
1301 | * |
1302 | * @param str String to sanitize. |
1303 | * |
1304 | * @remark The strings are treated as zero-terminated strings. |
1305 | */ |
1306 | void str_sanitize(char *str); |
1307 | |
1308 | /** |
1309 | * Replaces all invalid filename characters with whitespace. |
1310 | * |
1311 | * @param str String to sanitize. |
1312 | * |
1313 | * @remark The strings are treated as zero-terminated strings. |
1314 | */ |
1315 | void str_sanitize_filename(char *str); |
1316 | |
1317 | /** |
1318 | * Removes leading and trailing spaces and limits the use of multiple spaces. |
1319 | * |
1320 | * @ingroup Strings |
1321 | * |
1322 | * @param str String to clean up |
1323 | * |
1324 | * @remark The strings are treated as zero-terminated strings. |
1325 | */ |
1326 | void str_clean_whitespaces(char *str); |
1327 | |
1328 | /** |
1329 | * Skips leading non-whitespace characters. |
1330 | * |
1331 | * @ingroup Strings |
1332 | * |
1333 | * @param str Pointer to the string. |
1334 | * |
1335 | * @return Pointer to the first whitespace character found |
1336 | * within the string. |
1337 | * |
1338 | * @remark The strings are treated as zero-terminated strings. |
1339 | * @remark Whitespace is defined according to str_isspace. |
1340 | */ |
1341 | char *str_skip_to_whitespace(char *str); |
1342 | |
1343 | /** |
1344 | * @ingroup Strings |
1345 | * @see str_skip_to_whitespace |
1346 | */ |
1347 | const char *str_skip_to_whitespace_const(const char *str); |
1348 | |
1349 | /** |
1350 | * Skips leading whitespace characters. |
1351 | * |
1352 | * @ingroup Strings |
1353 | * |
1354 | * @param str Pointer to the string. |
1355 | * |
1356 | * Pointer to the first non-whitespace character found |
1357 | * within the string. |
1358 | * |
1359 | * @remark The strings are treated as zero-terminated strings. |
1360 | * @remark Whitespace is defined according to str_isspace. |
1361 | */ |
1362 | char *str_skip_whitespaces(char *str); |
1363 | |
1364 | /** |
1365 | * @ingroup Strings |
1366 | * @see str_skip_whitespaces |
1367 | */ |
1368 | const char *str_skip_whitespaces_const(const char *str); |
1369 | |
1370 | /** |
1371 | * Compares to strings case insensitively. |
1372 | * |
1373 | * @ingroup Strings |
1374 | * |
1375 | * @param a String to compare. |
1376 | * @param b String to compare. |
1377 | * |
1378 | * @return `< 0` - String a is less than string b |
1379 | * @return `0` - String a is equal to string b |
1380 | * @return `> 0` - String a is greater than string b |
1381 | * |
1382 | * @remark Only guaranteed to work with a-z/A-Z. |
1383 | * @remark The strings are treated as zero-terminated strings. |
1384 | */ |
1385 | int str_comp_nocase(const char *a, const char *b); |
1386 | |
1387 | /** |
1388 | * Compares up to num characters of two strings case insensitively. |
1389 | * |
1390 | * @ingroup Strings |
1391 | * |
1392 | * @param a String to compare. |
1393 | * @param b String to compare. |
1394 | * @param num Maximum characters to compare |
1395 | * |
1396 | * @return `< 0` - String a is less than string b |
1397 | * @return `0` - String a is equal to string b |
1398 | * @return `> 0` - String a is greater than string b |
1399 | * |
1400 | * @remark Only guaranteed to work with a-z/A-Z. |
1401 | * (use str_utf8_comp_nocase_num for unicode support) |
1402 | * @remark The strings are treated as zero-terminated strings. |
1403 | */ |
1404 | int str_comp_nocase_num(const char *a, const char *b, int num); |
1405 | |
1406 | /** |
1407 | * Compares two strings case sensitive. |
1408 | * |
1409 | * @ingroup Strings |
1410 | * |
1411 | * @param a String to compare. |
1412 | * @param b String to compare. |
1413 | * |
1414 | * @return `< 0` - String a is less than string b |
1415 | * @return `0` - String a is equal to string b |
1416 | * @return `> 0` - String a is greater than string b |
1417 | * |
1418 | * @remark The strings are treated as zero-terminated strings. |
1419 | */ |
1420 | int str_comp(const char *a, const char *b); |
1421 | |
1422 | /** |
1423 | * Compares up to num characters of two strings case sensitive. |
1424 | * |
1425 | * @ingroup Strings |
1426 | * |
1427 | * @param a String to compare. |
1428 | * @param b String to compare. |
1429 | * @param num Maximum characters to compare |
1430 | * |
1431 | * @return `< 0` - String a is less than string b |
1432 | * @return `0` - String a is equal to string b |
1433 | * @return `> 0` - String a is greater than string b |
1434 | * |
1435 | * @remark The strings are treated as zero-terminated strings. |
1436 | */ |
1437 | int str_comp_num(const char *a, const char *b, int num); |
1438 | |
1439 | /** |
1440 | * Compares two strings case insensitive, digit chars will be compared as numbers. |
1441 | * |
1442 | * @ingroup Strings |
1443 | * |
1444 | * @param a String to compare. |
1445 | * @param b String to compare. |
1446 | * |
1447 | * @return `< 0` - String a is less than string b |
1448 | * @return `0` - String a is equal to string b |
1449 | * @return `> 0` - String a is greater than string b |
1450 | * |
1451 | * @remark The strings are treated as zero-terminated strings. |
1452 | */ |
1453 | int str_comp_filenames(const char *a, const char *b); |
1454 | |
1455 | /* |
1456 | Function: str_startswith_nocase |
1457 | Checks case insensitive whether the string begins with a certain prefix. |
1458 | |
1459 | Parameter: |
1460 | str - String to check. |
1461 | prefix - Prefix to look for. |
1462 | |
1463 | Returns: |
1464 | A pointer to the string str after the string prefix, or 0 if |
1465 | the string prefix isn't a prefix of the string str. |
1466 | |
1467 | Remarks: |
1468 | - The strings are treated as zero-terminated strings. |
1469 | */ |
1470 | const char *str_startswith_nocase(const char *str, const char *prefix); |
1471 | |
1472 | /** |
1473 | * Checks case sensitive whether the string begins with a certain prefix. |
1474 | * |
1475 | * @ingroup Strings |
1476 | * |
1477 | * @param str String to check. |
1478 | * @param prefix Prefix to look for. |
1479 | * |
1480 | * @return A pointer to the string str after the string prefix, or 0 if |
1481 | * the string prefix isn't a prefix of the string str. |
1482 | * |
1483 | * @remark The strings are treated as zero-terminated strings. |
1484 | */ |
1485 | const char *str_startswith(const char *str, const char *prefix); |
1486 | |
1487 | /* |
1488 | Function: str_endswith_nocase |
1489 | Checks case insensitive whether the string ends with a certain suffix. |
1490 | |
1491 | Parameter: |
1492 | str - String to check. |
1493 | suffix - Suffix to look for. |
1494 | |
1495 | Returns: |
1496 | A pointer to the beginning of the suffix in the string str, or |
1497 | 0 if the string suffix isn't a suffix of the string str. |
1498 | |
1499 | Remarks: |
1500 | - The strings are treated as zero-terminated strings. |
1501 | */ |
1502 | const char *str_endswith_nocase(const char *str, const char *suffix); |
1503 | |
1504 | /* |
1505 | Function: str_endswith |
1506 | Checks case sensitive whether the string ends with a certain suffix. |
1507 | |
1508 | Parameter: |
1509 | str - String to check. |
1510 | suffix - Suffix to look for. |
1511 | |
1512 | Returns: |
1513 | A pointer to the beginning of the suffix in the string str, or |
1514 | 0 if the string suffix isn't a suffix of the string str. |
1515 | |
1516 | Remarks: |
1517 | - The strings are treated as zero-terminated strings. |
1518 | */ |
1519 | const char *str_endswith(const char *str, const char *suffix); |
1520 | |
1521 | /** |
1522 | * Computes the edit distance between two strings. |
1523 | * |
1524 | * @param a First string for the edit distance. |
1525 | * @param b Second string for the edit distance. |
1526 | * |
1527 | * @return The edit distance between the both strings. |
1528 | * |
1529 | * @remark The strings are treated as zero-terminated strings. |
1530 | */ |
1531 | int str_utf8_dist(const char *a, const char *b); |
1532 | |
1533 | /** |
1534 | * Computes the edit distance between two strings, allows buffers |
1535 | * to be passed in. |
1536 | * |
1537 | * @ingroup Strings |
1538 | * |
1539 | * @param a - First string for the edit distance. |
1540 | * @param b - Second string for the edit distance. |
1541 | * @param buf - Buffer for the function. |
1542 | * @param buf_len Length of the buffer, must be at least as long as |
1543 | * twice the length of both strings combined plus two. |
1544 | * |
1545 | * @return The edit distance between the both strings. |
1546 | * |
1547 | * @remark The strings are treated as zero-terminated strings. |
1548 | */ |
1549 | int str_utf8_dist_buffer(const char *a, const char *b, int *buf, int buf_len); |
1550 | |
1551 | /* |
1552 | Function: str_utf32_dist_buffer |
1553 | Computes the edit distance between two strings, allows buffers |
1554 | to be passed in. |
1555 | |
1556 | Parameters: |
1557 | a - First string for the edit distance. |
1558 | a_len - Length of the first string. |
1559 | b - Second string for the edit distance. |
1560 | b_len - Length of the second string. |
1561 | buf - Buffer for the function. |
1562 | buf_len - Length of the buffer, must be at least as long as |
1563 | the length of both strings combined plus two. |
1564 | |
1565 | Returns: |
1566 | The edit distance between the both strings. |
1567 | |
1568 | Remarks: |
1569 | - The strings are treated as zero-terminated strings. |
1570 | */ |
1571 | int str_utf32_dist_buffer(const int *a, int a_len, const int *b, int b_len, int *buf, int buf_len); |
1572 | |
1573 | /* |
1574 | Function: str_find_nocase |
1575 | Finds a string inside another string case insensitively. |
1576 | |
1577 | Parameters: |
1578 | haystack - String to search in |
1579 | needle - String to search for |
1580 | |
1581 | Returns: |
1582 | A pointer into haystack where the needle was found. |
1583 | Returns NULL if needle could not be found. |
1584 | |
1585 | Remarks: |
1586 | - Only guaranteed to work with a-z/A-Z. |
1587 | (use str_utf8_find_nocase for unicode support) |
1588 | - The strings are treated as zero-terminated strings. |
1589 | */ |
1590 | const char *str_find_nocase(const char *haystack, const char *needle); |
1591 | |
1592 | /* |
1593 | Function: str_find |
1594 | Finds a string inside another string case sensitive. |
1595 | |
1596 | Parameters: |
1597 | haystack - String to search in |
1598 | needle - String to search for |
1599 | |
1600 | Returns: |
1601 | A pointer into haystack where the needle was found. |
1602 | Returns NULL if needle could not be found. |
1603 | |
1604 | Remarks: |
1605 | - The strings are treated as zero-terminated strings. |
1606 | */ |
1607 | const char *str_find(const char *haystack, const char *needle); |
1608 | |
1609 | /** |
1610 | * Finds the last occurrence of a character |
1611 | * |
1612 | * @ingroup Strings |
1613 | * |
1614 | * @param haystack String to search in |
1615 | * @param needle Character to search for |
1616 | |
1617 | * @return A pointer into haystack where the needle was found. |
1618 | * Returns NULL if needle could not be found. |
1619 | * |
1620 | * @remark The strings are treated as zero-terminated strings. |
1621 | * @remark The zero-terminator character can also be found with this function. |
1622 | */ |
1623 | const char *str_rchr(const char *haystack, char needle); |
1624 | |
1625 | /** |
1626 | * Counts the number of occurrences of a character in a string. |
1627 | * |
1628 | * @ingroup Strings |
1629 | * |
1630 | * @param haystack String to count in |
1631 | * @param needle Character to count |
1632 | |
1633 | * @return The number of characters in the haystack string matching |
1634 | * the needle character. |
1635 | * |
1636 | * @remark The strings are treated as zero-terminated strings. |
1637 | * @remark The number of zero-terminator characters cannot be counted. |
1638 | */ |
1639 | int str_countchr(const char *haystack, char needle); |
1640 | |
1641 | /** |
1642 | * Takes a datablock and generates a hex string of it, with spaces between bytes. |
1643 | * |
1644 | * @param dst Buffer to fill with hex data. |
1645 | * @param dst_size Size of the buffer (at least 3 * data_size + 1 to contain all data). |
1646 | * @param data Data to turn into hex. |
1647 | * @param data_size Size of the data. |
1648 | * |
1649 | * @remark The destination buffer will be zero-terminated. |
1650 | */ |
1651 | void str_hex(char *dst, int dst_size, const void *data, int data_size); |
1652 | |
1653 | /** |
1654 | * Takes a datablock and generates a hex string of it, in the C style array format, |
1655 | * i.e. with bytes formatted in 0x00-0xFF notation and commas with spaces between the bytes. |
1656 | * The output can be split over multiple lines by specifying the maximum number of bytes |
1657 | * that should be printed per line. |
1658 | * |
1659 | * @param dst Buffer to fill with hex data. |
1660 | * @param dst_size Size of the buffer (at least 6 * data_size + 1 to contain all data). |
1661 | * @param data Data to turn into hex. |
1662 | * @param data_size Size of the data. |
1663 | * @param bytes_per_line After this many printed bytes a newline will be printed. |
1664 | * |
1665 | * @remark The destination buffer will be zero-terminated. |
1666 | */ |
1667 | void str_hex_cstyle(char *dst, int dst_size, const void *data, int data_size, int bytes_per_line = 12); |
1668 | |
1669 | /* |
1670 | Function: str_hex_decode |
1671 | Takes a hex string *without spaces between bytes* and returns a |
1672 | byte array. |
1673 | |
1674 | Parameters: |
1675 | dst - Buffer for the byte array |
1676 | dst_size - size of the buffer |
1677 | data - String to decode |
1678 | |
1679 | Returns: |
1680 | 2 - String doesn't exactly fit the buffer |
1681 | 1 - Invalid character in string |
1682 | 0 - Success |
1683 | |
1684 | Remarks: |
1685 | - The contents of the buffer is only valid on success |
1686 | */ |
1687 | int str_hex_decode(void *dst, int dst_size, const char *src); |
1688 | |
1689 | /* |
1690 | Function: str_base64 |
1691 | Takes a datablock and generates the base64 encoding of it. |
1692 | |
1693 | Parameters: |
1694 | dst - Buffer to fill with base64 data |
1695 | dst_size - Size of the buffer |
1696 | data - Data to turn into base64 |
1697 | data - Size of the data |
1698 | |
1699 | Remarks: |
1700 | - The destination buffer will be zero-terminated |
1701 | */ |
1702 | void str_base64(char *dst, int dst_size, const void *data, int data_size); |
1703 | |
1704 | /* |
1705 | Function: str_base64_decode |
1706 | Takes a base64 string without any whitespace and correct |
1707 | padding and returns a byte array. |
1708 | |
1709 | Parameters: |
1710 | dst - Buffer for the byte array |
1711 | dst_size - Size of the buffer |
1712 | data - String to decode |
1713 | |
1714 | Returns: |
1715 | <0 - Error |
1716 | >= 0 - Success, length of the resulting byte buffer |
1717 | |
1718 | Remarks: |
1719 | - The contents of the buffer is only valid on success |
1720 | */ |
1721 | int str_base64_decode(void *dst, int dst_size, const char *data); |
1722 | |
1723 | /* |
1724 | Function: str_timestamp |
1725 | Copies a time stamp in the format year-month-day_hour-minute-second to the string. |
1726 | |
1727 | Parameters: |
1728 | buffer - Pointer to a buffer that shall receive the time stamp string. |
1729 | buffer_size - Size of the buffer. |
1730 | |
1731 | Remarks: |
1732 | - Guarantees that buffer string will contain zero-termination. |
1733 | */ |
1734 | void str_timestamp(char *buffer, int buffer_size); |
1735 | void str_timestamp_format(char *buffer, int buffer_size, const char *format) |
1736 | GNUC_ATTRIBUTE((format(strftime, 3, 0))); |
1737 | void str_timestamp_ex(time_t time, char *buffer, int buffer_size, const char *format) |
1738 | GNUC_ATTRIBUTE((format(strftime, 4, 0))); |
1739 | |
1740 | /** |
1741 | * Parses a string into a timestamp following a specified format. |
1742 | * |
1743 | * @ingroup Timestamp |
1744 | * |
1745 | * @param string Pointer to the string to parse |
1746 | * @param format The time format to use (for example FORMAT_NOSPACE below) |
1747 | * @param timestamp Pointer to the timestamp result |
1748 | * |
1749 | * @return true on success, false if the string could not be parsed with the specified format |
1750 | * |
1751 | */ |
1752 | bool timestamp_from_str(const char *string, const char *format, time_t *timestamp) |
1753 | GNUC_ATTRIBUTE((format(strftime, 2, 0))); |
1754 | |
1755 | #define FORMAT_TIME "%H:%M:%S" |
1756 | #define FORMAT_SPACE "%Y-%m-%d %H:%M:%S" |
1757 | #define FORMAT_NOSPACE "%Y-%m-%d_%H-%M-%S" |
1758 | |
1759 | enum |
1760 | { |
1761 | TIME_DAYS, |
1762 | TIME_HOURS, |
1763 | TIME_MINS, |
1764 | TIME_HOURS_CENTISECS, |
1765 | TIME_MINS_CENTISECS, |
1766 | TIME_SECS_CENTISECS, |
1767 | }; |
1768 | |
1769 | /* |
1770 | Function: str_times |
1771 | Formats a time string. |
1772 | |
1773 | Parameters: |
1774 | centisecs - Time in centiseconds, minimum value clamped to 0 |
1775 | format - Format of the time string, see enum above, for example TIME_DAYS |
1776 | buffer - Pointer to a buffer that shall receive the time stamp string. |
1777 | buffer_size - Size of the buffer. |
1778 | |
1779 | Returns: |
1780 | Number of bytes written, -1 on invalid format or buffer_size <= 0 |
1781 | |
1782 | Remarks: |
1783 | - Guarantees that buffer string will contain zero-termination, assuming |
1784 | buffer_size > 0. |
1785 | */ |
1786 | int str_time(int64_t centisecs, int format, char *buffer, int buffer_size); |
1787 | int str_time_float(float secs, int format, char *buffer, int buffer_size); |
1788 | |
1789 | /* |
1790 | Function: str_escape |
1791 | Escapes \ and " characters in a string. |
1792 | |
1793 | Parameters: |
1794 | dst - Destination array pointer, gets increased, will point to |
1795 | the terminating null. |
1796 | src - Source array |
1797 | end - End of destination array |
1798 | */ |
1799 | void str_escape(char **dst, const char *src, const char *end); |
1800 | |
1801 | /** |
1802 | * @defgroup Filesystem |
1803 | * |
1804 | * Utilities for accessing the file system. |
1805 | */ |
1806 | |
1807 | /** |
1808 | * Lists the files and folders in a directory. |
1809 | * |
1810 | * @ingroup Filesystem |
1811 | * |
1812 | * @param dir Directory to list. |
1813 | * @param cb Callback function to call for each entry. |
1814 | * @param type Type of the directory. |
1815 | * @param user Pointer to give to the callback. |
1816 | * |
1817 | * @remark The strings are treated as zero-terminated strings. |
1818 | */ |
1819 | void fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, int type, void *user); |
1820 | |
1821 | /** |
1822 | * Lists the files and folders in a directory and gets additional file information. |
1823 | * |
1824 | * @ingroup Filesystem |
1825 | * |
1826 | * @param dir Directory to list. |
1827 | * @param cb Callback function to call for each entry. |
1828 | * @param type Type of the directory. |
1829 | * @param user Pointer to give to the callback. |
1830 | * |
1831 | * @remark The strings are treated as zero-terminated strings. |
1832 | */ |
1833 | void fs_listdir_fileinfo(const char *dir, FS_LISTDIR_CALLBACK_FILEINFO cb, int type, void *user); |
1834 | |
1835 | /** |
1836 | * Creates a directory. |
1837 | * |
1838 | * @ingroup Filesystem |
1839 | * |
1840 | * @param path Directory to create. |
1841 | * |
1842 | * @return 0 on success. Negative value on failure. |
1843 | * |
1844 | * @remark Does not create several directories if needed. "a/b/c" will |
1845 | * result in a failure if b or a does not exist. |
1846 | * |
1847 | * @remark The strings are treated as zero-terminated strings. |
1848 | */ |
1849 | int fs_makedir(const char *path); |
1850 | |
1851 | /** |
1852 | * Removes a directory. |
1853 | * |
1854 | * @ingroup Filesystem |
1855 | * |
1856 | * @param path Directory to remove. |
1857 | * |
1858 | * @return 0 on success. Negative value on failure. |
1859 | * |
1860 | * @remark Cannot remove a non-empty directory. |
1861 | * |
1862 | * @remark The strings are treated as zero-terminated strings. |
1863 | */ |
1864 | int fs_removedir(const char *path); |
1865 | |
1866 | /** |
1867 | * Recursively creates parent directories for a file or directory. |
1868 | * |
1869 | * @ingroup Filesystem |
1870 | * |
1871 | * @param path File or directory for which to create parent directories. |
1872 | * |
1873 | * @return 0 on success. Negative value on failure. |
1874 | * |
1875 | * @remark The strings are treated as zero-terminated strings. |
1876 | */ |
1877 | int fs_makedir_rec_for(const char *path); |
1878 | |
1879 | /** |
1880 | * Fetches per user configuration directory. |
1881 | * |
1882 | * @ingroup Filesystem |
1883 | * |
1884 | * @param appname Name of the application. |
1885 | * @param path Buffer that will receive the storage path. |
1886 | * @param max Size of the buffer. |
1887 | * |
1888 | * @return 0 on success. Negative value on failure. |
1889 | * |
1890 | * @remark Returns ~/.appname on UNIX based systems. |
1891 | * @remark Returns ~/Library/Applications Support/appname on macOS. |
1892 | * @remark Returns %APPDATA%/Appname on Windows based systems. |
1893 | * |
1894 | * @remark The strings are treated as zero-terminated strings. |
1895 | */ |
1896 | int fs_storage_path(const char *appname, char *path, int max); |
1897 | |
1898 | /** |
1899 | * Checks if a file exists. |
1900 | * |
1901 | * @ingroup Filesystem |
1902 | * |
1903 | * @param path the path to check. |
1904 | * |
1905 | * @return 1 if a file with the given path exists, |
1906 | * 0 on failure or if the file does not exist. |
1907 | * |
1908 | * @remark The strings are treated as zero-terminated strings. |
1909 | */ |
1910 | int fs_is_file(const char *path); |
1911 | |
1912 | /** |
1913 | * Checks if a folder exists. |
1914 | * |
1915 | * @ingroup Filesystem |
1916 | * |
1917 | * @param path the path to check. |
1918 | * |
1919 | * @return 1 if a folder with the given path exists, |
1920 | * 0 on failure or if the folder does not exist. |
1921 | * |
1922 | * @remark The strings are treated as zero-terminated strings. |
1923 | */ |
1924 | int fs_is_dir(const char *path); |
1925 | |
1926 | /** |
1927 | * Checks whether a given path is relative or absolute. |
1928 | * |
1929 | * @ingroup Filesystem |
1930 | * |
1931 | * @param path Path to check. |
1932 | * |
1933 | * @return 1 if relative, 0 if absolute. |
1934 | * |
1935 | * @remark The strings are treated as zero-terminated strings. |
1936 | */ |
1937 | int fs_is_relative_path(const char *path); |
1938 | |
1939 | /** |
1940 | * Changes the current working directory. |
1941 | * |
1942 | * @ingroup Filesystem |
1943 | * |
1944 | * @param path New working directory path. |
1945 | * |
1946 | * @return 0 on success, 1 on failure. |
1947 | * |
1948 | * @remark The strings are treated as zero-terminated strings. |
1949 | */ |
1950 | int fs_chdir(const char *path); |
1951 | |
1952 | /** |
1953 | * Gets the current working directory. |
1954 | * |
1955 | * @ingroup Filesystem |
1956 | * |
1957 | * @param buffer Buffer that will receive the current working directory. |
1958 | * @param buffer_size Size of the buffer. |
1959 | * |
1960 | * @return Pointer to the buffer on success, nullptr on failure. |
1961 | * |
1962 | * @remark The strings are treated as zero-terminated strings. |
1963 | */ |
1964 | char *fs_getcwd(char *buffer, int buffer_size); |
1965 | |
1966 | /** |
1967 | * Gets the name of a file or folder specified by a path, |
1968 | * i.e. the last segment of the path. |
1969 | * |
1970 | * @ingroup Filesystem |
1971 | * |
1972 | * @param path Path from which to retrieve the filename. |
1973 | * |
1974 | * @return Filename of the path. |
1975 | * |
1976 | * @remark Supports forward and backward slashes as path segment separator. |
1977 | * @remark No distinction between files and folders is being made. |
1978 | * @remark The strings are treated as zero-terminated strings. |
1979 | */ |
1980 | const char *fs_filename(const char *path); |
1981 | |
1982 | /** |
1983 | * Splits a filename into name (without extension) and file extension. |
1984 | * |
1985 | * @ingroup Filesystem |
1986 | * |
1987 | * @param filename The filename to split. |
1988 | * @param name Buffer that will receive the name without extension, may be nullptr. |
1989 | * @param name_size Size of the name buffer (ignored if name is nullptr). |
1990 | * @param extension Buffer that will receive the extension, may be nullptr. |
1991 | * @param extension_size Size of the extension buffer (ignored if extension is nullptr). |
1992 | * |
1993 | * @remark Does NOT handle forward and backward slashes. |
1994 | * @remark No distinction between files and folders is being made. |
1995 | * @remark The strings are treated as zero-terminated strings. |
1996 | */ |
1997 | void fs_split_file_extension(const char *filename, char *name, size_t name_size, char *extension = nullptr, size_t extension_size = 0); |
1998 | |
1999 | /** |
2000 | * Get the parent directory of a directory. |
2001 | * |
2002 | * @ingroup Filesystem |
2003 | * |
2004 | * @param path Path of the directory. The parent will be store in this buffer as well. |
2005 | * |
2006 | * @return 0 on success, 1 on failure. |
2007 | * |
2008 | * @remark The strings are treated as zero-terminated strings. |
2009 | */ |
2010 | int fs_parent_dir(char *path); |
2011 | |
2012 | /** |
2013 | * Deletes a file. |
2014 | * |
2015 | * @ingroup Filesystem |
2016 | * |
2017 | * @param filename Path of the file to delete. |
2018 | * |
2019 | * @return 0 on success, 1 on failure. |
2020 | * |
2021 | * @remark The strings are treated as zero-terminated strings. |
2022 | * @remark Returns an error if the path specifies a directory name. |
2023 | */ |
2024 | int fs_remove(const char *filename); |
2025 | |
2026 | /** |
2027 | * Renames the file or directory. If the paths differ the file will be moved. |
2028 | * |
2029 | * @ingroup Filesystem |
2030 | * |
2031 | * @param oldname The current path of a file or directory. |
2032 | * @param newname The new path for the file or directory. |
2033 | * |
2034 | * @return 0 on success, 1 on failure. |
2035 | * |
2036 | * @remark The strings are treated as zero-terminated strings. |
2037 | */ |
2038 | int fs_rename(const char *oldname, const char *newname); |
2039 | |
2040 | /** |
2041 | * Gets the creation and the last modification date of a file or directory. |
2042 | * |
2043 | * @ingroup Filesystem |
2044 | * |
2045 | * @param name Path of a file or directory. |
2046 | * @param created Pointer where the creation time will be stored. |
2047 | * @param modified Pointer where the modification time will be stored. |
2048 | * |
2049 | * @return 0 on success, non-zero on failure. |
2050 | * |
2051 | * @remark The strings are treated as zero-terminated strings. |
2052 | * @remark Returned time is in seconds since UNIX Epoch. |
2053 | */ |
2054 | int fs_file_time(const char *name, time_t *created, time_t *modified); |
2055 | |
2056 | /* |
2057 | Group: Undocumented |
2058 | */ |
2059 | |
2060 | /* |
2061 | Function: net_tcp_connect_non_blocking |
2062 | |
2063 | DOCTODO: serp |
2064 | */ |
2065 | int net_tcp_connect_non_blocking(NETSOCKET sock, NETADDR bindaddr); |
2066 | |
2067 | /* |
2068 | Function: net_set_non_blocking |
2069 | |
2070 | DOCTODO: serp |
2071 | */ |
2072 | int net_set_non_blocking(NETSOCKET sock); |
2073 | |
2074 | /* |
2075 | Function: net_set_non_blocking |
2076 | |
2077 | DOCTODO: serp |
2078 | */ |
2079 | int net_set_blocking(NETSOCKET sock); |
2080 | |
2081 | /* |
2082 | Function: net_errno |
2083 | |
2084 | DOCTODO: serp |
2085 | */ |
2086 | int net_errno(); |
2087 | |
2088 | /* |
2089 | Function: net_would_block |
2090 | |
2091 | DOCTODO: serp |
2092 | */ |
2093 | int net_would_block(); |
2094 | |
2095 | int net_socket_read_wait(NETSOCKET sock, int time); |
2096 | |
2097 | /** |
2098 | * Swaps the endianness of data. Each element is swapped individually by reversing its bytes. |
2099 | * |
2100 | * @param data Pointer to data to be swapped. |
2101 | * @param elem_size Size in bytes of each element. |
2102 | * @param num Number of elements. |
2103 | * |
2104 | * @remark The caller must ensure that the data is at least `elem_size * num` bytes in size. |
2105 | */ |
2106 | void swap_endian(void *data, unsigned elem_size, unsigned num); |
2107 | |
2108 | typedef struct |
2109 | { |
2110 | uint64_t sent_packets; |
2111 | uint64_t sent_bytes; |
2112 | uint64_t recv_packets; |
2113 | uint64_t recv_bytes; |
2114 | } NETSTATS; |
2115 | |
2116 | void net_stats(NETSTATS *stats); |
2117 | |
2118 | int str_toint(const char *str); |
2119 | bool str_toint(const char *str, int *out); |
2120 | int str_toint_base(const char *str, int base); |
2121 | unsigned long str_toulong_base(const char *str, int base); |
2122 | int64_t str_toint64_base(const char *str, int base = 10); |
2123 | float str_tofloat(const char *str); |
2124 | bool str_tofloat(const char *str, float *out); |
2125 | |
2126 | /** |
2127 | * Determines whether a character is whitespace. |
2128 | * |
2129 | * @ingroup Strings |
2130 | * |
2131 | * @param c the character to check |
2132 | * |
2133 | * @return 1 if the character is whitespace, 0 otherwise. |
2134 | * |
2135 | * @remark The following characters are considered whitespace: ' ', '\n', '\r', '\t' |
2136 | */ |
2137 | int str_isspace(char c); |
2138 | |
2139 | char str_uppercase(char c); |
2140 | |
2141 | bool str_isnum(char c); |
2142 | |
2143 | int str_isallnum(const char *str); |
2144 | |
2145 | int str_isallnum_hex(const char *str); |
2146 | |
2147 | unsigned str_quickhash(const char *str); |
2148 | |
2149 | int str_utf8_to_skeleton(const char *str, int *buf, int buf_len); |
2150 | |
2151 | /* |
2152 | Function: str_utf8_comp_confusable |
2153 | Compares two strings for visual appearance. |
2154 | |
2155 | Parameters: |
2156 | str1 - String to compare. |
2157 | str2 - String to compare. |
2158 | |
2159 | Returns: |
2160 | 0 if the strings are confusable. |
2161 | !=0 otherwise. |
2162 | */ |
2163 | int str_utf8_comp_confusable(const char *str1, const char *str2); |
2164 | |
2165 | /* |
2166 | Function: str_utf8_tolower |
2167 | Converts the given Unicode codepoint to lowercase (locale insensitive). |
2168 | |
2169 | Parameters: |
2170 | code - Unicode codepoint to convert. |
2171 | |
2172 | Returns: |
2173 | Lowercase codepoint |
2174 | */ |
2175 | int str_utf8_tolower(int code); |
2176 | |
2177 | /* |
2178 | Function: str_utf8_comp_nocase |
2179 | Compares two utf8 strings case insensitively. |
2180 | |
2181 | Parameters: |
2182 | a - String to compare. |
2183 | b - String to compare. |
2184 | |
2185 | Returns: |
2186 | <0 - String a is less than string b |
2187 | 0 - String a is equal to string b |
2188 | >0 - String a is greater than string b |
2189 | */ |
2190 | int str_utf8_comp_nocase(const char *a, const char *b); |
2191 | |
2192 | /* |
2193 | Function: str_utf8_comp_nocase_num |
2194 | Compares up to num bytes of two utf8 strings case insensitively. |
2195 | |
2196 | Parameters: |
2197 | a - String to compare. |
2198 | b - String to compare. |
2199 | num - Maximum bytes to compare |
2200 | |
2201 | Returns: |
2202 | <0 - String a is less than string b |
2203 | 0 - String a is equal to string b |
2204 | >0 - String a is greater than string b |
2205 | */ |
2206 | int str_utf8_comp_nocase_num(const char *a, const char *b, int num); |
2207 | |
2208 | /* |
2209 | Function: str_utf8_find_nocase |
2210 | Finds a utf8 string inside another utf8 string case insensitively. |
2211 | |
2212 | Parameters: |
2213 | haystack - String to search in |
2214 | needle - String to search for |
2215 | end - A pointer that will be set to a pointer into haystack directly behind the |
2216 | last character where the needle was found. Will be set to nullptr if needle |
2217 | could not be found. Optional parameter. |
2218 | |
2219 | Returns: |
2220 | A pointer into haystack where the needle was found. |
2221 | Returns NULL if needle could not be found. |
2222 | |
2223 | Remarks: |
2224 | - The strings are treated as zero-terminated strings. |
2225 | */ |
2226 | const char *str_utf8_find_nocase(const char *haystack, const char *needle, const char **end = nullptr); |
2227 | |
2228 | /* |
2229 | Function: str_utf8_isspace |
2230 | Checks whether the given Unicode codepoint renders as space. |
2231 | |
2232 | Parameters: |
2233 | code - Unicode codepoint to check. |
2234 | |
2235 | Returns: |
2236 | 0 if the codepoint does not render as space, != 0 if it does. |
2237 | */ |
2238 | int str_utf8_isspace(int code); |
2239 | |
2240 | int str_utf8_isstart(char c); |
2241 | |
2242 | /* |
2243 | Function: str_utf8_skip_whitespaces |
2244 | Skips leading characters that render as spaces. |
2245 | |
2246 | Parameters: |
2247 | str - Pointer to the string. |
2248 | |
2249 | Returns: |
2250 | Pointer to the first non-whitespace character found |
2251 | within the string. |
2252 | |
2253 | Remarks: |
2254 | - The strings are treated as zero-terminated strings. |
2255 | */ |
2256 | const char *str_utf8_skip_whitespaces(const char *str); |
2257 | |
2258 | /* |
2259 | Function: str_utf8_trim_right |
2260 | Removes trailing characters that render as spaces by modifying |
2261 | the string in-place. |
2262 | |
2263 | Parameters: |
2264 | param - Pointer to the string. |
2265 | |
2266 | Remarks: |
2267 | - The strings are treated as zero-terminated strings. |
2268 | - The string is modified in-place. |
2269 | */ |
2270 | void str_utf8_trim_right(char *param); |
2271 | |
2272 | /* |
2273 | Function: str_utf8_rewind |
2274 | Moves a cursor backwards in an utf8 string |
2275 | |
2276 | Parameters: |
2277 | str - utf8 string |
2278 | cursor - position in the string |
2279 | |
2280 | Returns: |
2281 | New cursor position. |
2282 | |
2283 | Remarks: |
2284 | - Won't move the cursor less then 0 |
2285 | */ |
2286 | int str_utf8_rewind(const char *str, int cursor); |
2287 | |
2288 | /* |
2289 | Function: str_utf8_fix_truncation |
2290 | Fixes truncation of a Unicode character at the end of a UTF-8 |
2291 | string. |
2292 | |
2293 | Returns: |
2294 | The new string length. |
2295 | |
2296 | Parameters: |
2297 | str - utf8 string |
2298 | */ |
2299 | int str_utf8_fix_truncation(char *str); |
2300 | |
2301 | /* |
2302 | Function: str_utf8_forward |
2303 | Moves a cursor forwards in an utf8 string |
2304 | |
2305 | Parameters: |
2306 | str - utf8 string |
2307 | cursor - position in the string |
2308 | |
2309 | Returns: |
2310 | New cursor position. |
2311 | |
2312 | Remarks: |
2313 | - Won't move the cursor beyond the zero termination marker |
2314 | */ |
2315 | int str_utf8_forward(const char *str, int cursor); |
2316 | |
2317 | /* |
2318 | Function: str_utf8_decode |
2319 | Decodes a utf8 codepoint |
2320 | |
2321 | Parameters: |
2322 | ptr - Pointer to a utf8 string. This pointer will be moved forward. |
2323 | |
2324 | Returns: |
2325 | The Unicode codepoint. -1 for invalid input and 0 for end of string. |
2326 | |
2327 | Remarks: |
2328 | - This function will also move the pointer forward. |
2329 | - You may call this function again after an error occurred. |
2330 | */ |
2331 | int str_utf8_decode(const char **ptr); |
2332 | |
2333 | /* |
2334 | Function: str_utf8_encode |
2335 | Encode an utf8 character |
2336 | |
2337 | Parameters: |
2338 | ptr - Pointer to a buffer that should receive the data. Should be able to hold at least 4 bytes. |
2339 | |
2340 | Returns: |
2341 | Number of bytes put into the buffer. |
2342 | |
2343 | Remarks: |
2344 | - Does not do zero termination of the string. |
2345 | */ |
2346 | int str_utf8_encode(char *ptr, int chr); |
2347 | |
2348 | /* |
2349 | Function: str_utf8_check |
2350 | Checks if a strings contains just valid utf8 characters. |
2351 | |
2352 | Parameters: |
2353 | str - Pointer to a possible utf8 string. |
2354 | |
2355 | Returns: |
2356 | 0 - invalid characters found. |
2357 | 1 - only valid characters found. |
2358 | |
2359 | Remarks: |
2360 | - The string is treated as zero-terminated utf8 string. |
2361 | */ |
2362 | int str_utf8_check(const char *str); |
2363 | |
2364 | /* |
2365 | Function: str_utf8_stats |
2366 | Determines the byte size and utf8 character count of a utf8 string. |
2367 | |
2368 | Parameters: |
2369 | str - Pointer to the string. |
2370 | max_size - Maximum number of bytes to count. |
2371 | max_count - Maximum number of utf8 characters to count. |
2372 | size - Pointer to store size (number of non-zero bytes) of the string. |
2373 | count - Pointer to store count of utf8 characters of the string. |
2374 | |
2375 | Remarks: |
2376 | - The string is treated as zero-terminated utf8 string. |
2377 | - It's the user's responsibility to make sure the bounds are aligned. |
2378 | */ |
2379 | void str_utf8_stats(const char *str, size_t max_size, size_t max_count, size_t *size, size_t *count); |
2380 | |
2381 | /** |
2382 | * Converts a byte offset of a utf8 string to the utf8 character offset. |
2383 | * |
2384 | * @param text Pointer to the string. |
2385 | * @param byte_offset Offset in bytes. |
2386 | * |
2387 | * @return Offset in utf8 characters. Clamped to the maximum length of the string in utf8 characters. |
2388 | * |
2389 | * @remark The string is treated as a zero-terminated utf8 string. |
2390 | * @remark It's the user's responsibility to make sure the bounds are aligned. |
2391 | */ |
2392 | size_t str_utf8_offset_bytes_to_chars(const char *str, size_t byte_offset); |
2393 | |
2394 | /** |
2395 | * Converts a utf8 character offset of a utf8 string to the byte offset. |
2396 | * |
2397 | * @param text Pointer to the string. |
2398 | * @param char_offset Offset in utf8 characters. |
2399 | * |
2400 | * @return Offset in bytes. Clamped to the maximum length of the string in bytes. |
2401 | * |
2402 | * @remark The string is treated as a zero-terminated utf8 string. |
2403 | * @remark It's the user's responsibility to make sure the bounds are aligned. |
2404 | */ |
2405 | size_t str_utf8_offset_chars_to_bytes(const char *str, size_t char_offset); |
2406 | |
2407 | /* |
2408 | Function: str_next_token |
2409 | Writes the next token after str into buf, returns the rest of the string. |
2410 | |
2411 | Parameters: |
2412 | str - Pointer to string. |
2413 | delim - Delimiter for tokenization. |
2414 | buffer - Buffer to store token in. |
2415 | buffer_size - Size of the buffer. |
2416 | |
2417 | Returns: |
2418 | Pointer to rest of the string. |
2419 | |
2420 | Remarks: |
2421 | - The token is always null-terminated. |
2422 | */ |
2423 | const char *str_next_token(const char *str, const char *delim, char *buffer, int buffer_size); |
2424 | |
2425 | /* |
2426 | Function: str_in_list |
2427 | Checks if needle is in list delimited by delim |
2428 | |
2429 | Parameters: |
2430 | list - List |
2431 | delim - List delimiter. |
2432 | needle - Item that is being looked for. |
2433 | |
2434 | Returns: |
2435 | 1 - Item is in list. |
2436 | 0 - Item isn't in list. |
2437 | */ |
2438 | int str_in_list(const char *list, const char *delim, const char *needle); |
2439 | |
2440 | /** |
2441 | * Packs 4 big endian bytes into an unsigned. |
2442 | * |
2443 | * @param bytes Pointer to an array of bytes that will be packed. |
2444 | * |
2445 | * @return The packed unsigned. |
2446 | * |
2447 | * @remark Assumes the passed array is least 4 bytes in size. |
2448 | * @remark Assumes unsigned is 4 bytes in size. |
2449 | * |
2450 | * @see uint_to_bytes_be |
2451 | */ |
2452 | unsigned bytes_be_to_uint(const unsigned char *bytes); |
2453 | |
2454 | /** |
2455 | * Packs an unsigned into 4 big endian bytes. |
2456 | * |
2457 | * @param bytes Pointer to an array where the bytes will be stored. |
2458 | * @param value The values that will be packed into the array. |
2459 | * |
2460 | * @remark Assumes the passed array is least 4 bytes in size. |
2461 | * @remark Assumes unsigned is 4 bytes in size. |
2462 | * |
2463 | * @see bytes_be_to_uint |
2464 | */ |
2465 | void uint_to_bytes_be(unsigned char *bytes, unsigned value); |
2466 | |
2467 | /** |
2468 | * @defgroup Shell |
2469 | * Shell, process management, OS specific functionality. |
2470 | */ |
2471 | |
2472 | /** |
2473 | * Returns the ID of the current process. |
2474 | * |
2475 | * @ingroup Shell |
2476 | * |
2477 | * @return PID of the current process. |
2478 | */ |
2479 | int pid(); |
2480 | |
2481 | /** |
2482 | * Fixes the command line arguments to be encoded in UTF-8 on all systems. |
2483 | * |
2484 | * @ingroup Shell |
2485 | * |
2486 | * @param argc A pointer to the argc parameter that was passed to the main function. |
2487 | * @param argv A pointer to the argv parameter that was passed to the main function. |
2488 | * |
2489 | * @remark You need to call @link cmdline_free @endlink once you're no longer using the results. |
2490 | */ |
2491 | void cmdline_fix(int *argc, const char ***argv); |
2492 | |
2493 | /** |
2494 | * Frees memory that was allocated by @link cmdline_fix @endlink. |
2495 | * |
2496 | * @ingroup Shell |
2497 | * |
2498 | * @param argc The argc obtained from `cmdline_fix`. |
2499 | * @param argv The argv obtained from `cmdline_fix`. |
2500 | */ |
2501 | void cmdline_free(int argc, const char **argv); |
2502 | |
2503 | #if defined(CONF_FAMILY_WINDOWS) |
2504 | /** |
2505 | * A handle for a process. |
2506 | * |
2507 | * @ingroup Shell |
2508 | */ |
2509 | typedef void *PROCESS; |
2510 | /** |
2511 | * A handle that denotes an invalid process. |
2512 | * |
2513 | * @ingroup Shell |
2514 | */ |
2515 | constexpr PROCESS INVALID_PROCESS = nullptr; |
2516 | #else |
2517 | /** |
2518 | * A handle for a process. |
2519 | * |
2520 | * @ingroup Shell |
2521 | */ |
2522 | typedef pid_t PROCESS; |
2523 | /** |
2524 | * A handle that denotes an invalid process. |
2525 | * |
2526 | * @ingroup Shell |
2527 | */ |
2528 | constexpr PROCESS INVALID_PROCESS = 0; |
2529 | #endif |
2530 | |
2531 | /** |
2532 | * Determines the initial window state when using @link shell_execute @endlink |
2533 | * to execute a process. |
2534 | * |
2535 | * @ingroup Shell |
2536 | * |
2537 | * @remark Currently only supported on Windows. |
2538 | */ |
2539 | enum class EShellExecuteWindowState |
2540 | { |
2541 | /** |
2542 | * The process window is opened in the foreground and activated. |
2543 | */ |
2544 | FOREGROUND, |
2545 | |
2546 | /** |
2547 | * The process window is opened in the background without focus. |
2548 | */ |
2549 | BACKGROUND, |
2550 | }; |
2551 | |
2552 | /** |
2553 | * Executes a given file. |
2554 | * |
2555 | * @ingroup Shell |
2556 | * |
2557 | * @param file The file to execute. |
2558 | * @param window_state The window state how the process window should be shown. |
2559 | * |
2560 | * @return Handle of the new process, or @link INVALID_PROCESS @endlink on error. |
2561 | */ |
2562 | PROCESS shell_execute(const char *file, EShellExecuteWindowState window_state); |
2563 | |
2564 | /** |
2565 | * Sends kill signal to a process. |
2566 | * |
2567 | * @ingroup Shell |
2568 | * |
2569 | * @param process Handle of the process to kill. |
2570 | * |
2571 | * @return `1` on success, `0` on error. |
2572 | */ |
2573 | int kill_process(PROCESS process); |
2574 | |
2575 | /** |
2576 | * Checks if a process is alive. |
2577 | * |
2578 | * @ingroup Shell |
2579 | * |
2580 | * @param process Handle/PID of the process. |
2581 | * |
2582 | * @return `true` if the process is currently running, |
2583 | * `false` if the process is not running (dead). |
2584 | */ |
2585 | bool is_process_alive(PROCESS process); |
2586 | |
2587 | /** |
2588 | * Opens a link in the browser. |
2589 | * |
2590 | * @ingroup Shell |
2591 | * |
2592 | * @param link The link to open in a browser. |
2593 | * |
2594 | * @return `1` on success, `0` on failure. |
2595 | * |
2596 | * @remark The strings are treated as zero-terminated strings. |
2597 | * @remark This may not be called with untrusted input or it'll result in arbitrary code execution, especially on Windows. |
2598 | */ |
2599 | int open_link(const char *link); |
2600 | |
2601 | /** |
2602 | * Opens a file or directory with default program. |
2603 | * |
2604 | * @ingroup Shell |
2605 | * |
2606 | * @param path The path to open. |
2607 | * |
2608 | * @return `1` on success, `0` on failure. |
2609 | * |
2610 | * @remark The strings are treated as zero-terminated strings. |
2611 | * @remark This may not be called with untrusted input or it'll result in arbitrary code execution, especially on Windows. |
2612 | */ |
2613 | int open_file(const char *path); |
2614 | |
2615 | /** |
2616 | * @defgroup Secure-Random |
2617 | * Secure random number generation. |
2618 | */ |
2619 | |
2620 | /** |
2621 | * Generates a null-terminated password of length `2 * random_length`. |
2622 | * |
2623 | * @ingroup Secure-Random |
2624 | * |
2625 | * @param buffer Pointer to the start of the output buffer. |
2626 | * @param length Length of the buffer. |
2627 | * @param random Pointer to a randomly-initialized array of shorts. |
2628 | * @param random_length Length of the short array. |
2629 | */ |
2630 | void generate_password(char *buffer, unsigned length, const unsigned short *random, unsigned random_length); |
2631 | |
2632 | /** |
2633 | * Initializes the secure random module. |
2634 | * You *MUST* check the return value of this function. |
2635 | * |
2636 | * @ingroup Secure-Random |
2637 | * |
2638 | * @return `0` on success. |
2639 | */ |
2640 | [[nodiscard]] int secure_random_init(); |
2641 | |
2642 | /** |
2643 | * Uninitializes the secure random module. |
2644 | * |
2645 | * @ingroup Secure-Random |
2646 | * |
2647 | * @return `0` on success. |
2648 | */ |
2649 | int secure_random_uninit(); |
2650 | |
2651 | /** |
2652 | * Fills the buffer with the specified amount of random password characters. |
2653 | * |
2654 | * @ingroup Secure-Random |
2655 | * |
2656 | * @param buffer Pointer to the start of the buffer. |
2657 | * @param length Length of the buffer. |
2658 | * @param pw_length Length of the desired password. |
2659 | * |
2660 | * @remark The desired password length must be greater or equal to 6, |
2661 | * even and smaller or equal to 128. |
2662 | */ |
2663 | void secure_random_password(char *buffer, unsigned length, unsigned pw_length); |
2664 | |
2665 | /** |
2666 | * Fills the buffer with the specified amount of random bytes. |
2667 | * |
2668 | * @ingroup Secure-Random |
2669 | * |
2670 | * @param buffer Pointer to the start of the buffer. |
2671 | * @param length Length of the buffer. |
2672 | */ |
2673 | void secure_random_fill(void *bytes, unsigned length); |
2674 | |
2675 | /** |
2676 | * Returns random `int`. |
2677 | * |
2678 | * @ingroup Secure-Random |
2679 | * |
2680 | * @return Random int. |
2681 | * |
2682 | * @remark Can be used as a replacement for the `rand` function. |
2683 | */ |
2684 | int secure_rand(); |
2685 | |
2686 | /** |
2687 | * Returns a random nonnegative integer below the given number, |
2688 | * with a uniform distribution. |
2689 | * |
2690 | * @ingroup Secure-Random |
2691 | * |
2692 | * @param below Upper limit (exclusive) of integers to return. |
2693 | * |
2694 | * @return Random nonnegative below the given number. |
2695 | */ |
2696 | int secure_rand_below(int below); |
2697 | |
2698 | /** |
2699 | * Returns a human-readable version string of the operating system. |
2700 | * |
2701 | * @ingroup Shell |
2702 | * |
2703 | * @param version Buffer to use for the output. |
2704 | * @param length Length of the output buffer. |
2705 | * |
2706 | * @return `true` on success, `false` on failure. |
2707 | */ |
2708 | bool os_version_str(char *version, size_t length); |
2709 | |
2710 | /** |
2711 | * Returns a string of the preferred locale of the user / operating system. |
2712 | * The string conforms to [RFC 3066](https://www.ietf.org/rfc/rfc3066.txt) |
2713 | * and only contains the characters `a`-`z`, `A`-`Z`, `0`-`9` and `-`. |
2714 | * If the preferred locale could not be determined this function |
2715 | * falls back to the locale `"en-US"`. |
2716 | * |
2717 | * @ingroup Shell |
2718 | * |
2719 | * @param locale Buffer to use for the output. |
2720 | * @param length Length of the output buffer. |
2721 | * |
2722 | * @remark The destination buffer will be zero-terminated. |
2723 | */ |
2724 | void os_locale_str(char *locale, size_t length); |
2725 | |
2726 | #if defined(CONF_EXCEPTION_HANDLING) |
2727 | /** |
2728 | * @defgroup Exception-Handling |
2729 | * Exception handling (crash logging). |
2730 | */ |
2731 | |
2732 | /** |
2733 | * Initializes the exception handling module. |
2734 | * |
2735 | * @ingroup Exception-Handling |
2736 | */ |
2737 | void init_exception_handler(); |
2738 | |
2739 | /** |
2740 | * Sets the filename for writing the crash log. |
2741 | * |
2742 | * @ingroup Exception-Handling |
2743 | * |
2744 | * @param log_file_path Absolute path to which crash log file should be written. |
2745 | */ |
2746 | void set_exception_handler_log_file(const char *log_file_path); |
2747 | #endif |
2748 | |
2749 | /** |
2750 | * Fetches a sample from a high resolution timer and converts it in nanoseconds. |
2751 | * |
2752 | * @ingroup Time |
2753 | * |
2754 | * @return Current value of the timer in nanoseconds. |
2755 | */ |
2756 | std::chrono::nanoseconds time_get_nanoseconds(); |
2757 | |
2758 | int net_socket_read_wait(NETSOCKET sock, std::chrono::nanoseconds nanoseconds); |
2759 | |
2760 | /** |
2761 | * Fixes the command line arguments to be encoded in UTF-8 on all systems. |
2762 | * This is a RAII wrapper for @link cmdline_fix @endlink and @link cmdline_free @endlink. |
2763 | * |
2764 | * @ingroup Shell |
2765 | */ |
2766 | class CCmdlineFix |
2767 | { |
2768 | int m_Argc; |
2769 | const char **m_ppArgv; |
2770 | |
2771 | public: |
2772 | CCmdlineFix(int *pArgc, const char ***pppArgv) |
2773 | { |
2774 | cmdline_fix(argc: pArgc, argv: pppArgv); |
2775 | m_Argc = *pArgc; |
2776 | m_ppArgv = *pppArgv; |
2777 | } |
2778 | ~CCmdlineFix() |
2779 | { |
2780 | cmdline_free(argc: m_Argc, argv: m_ppArgv); |
2781 | } |
2782 | }; |
2783 | |
2784 | #if defined(CONF_FAMILY_WINDOWS) |
2785 | /** |
2786 | * Converts a UTF-8 encoded string to a wide character string |
2787 | * for use with the Windows API. |
2788 | * |
2789 | * @ingroup Shell |
2790 | * |
2791 | * @param str The UTF-8 encoded string to convert. |
2792 | * |
2793 | * @return The argument as a wide character string. |
2794 | * |
2795 | * @remark The argument string must be zero-terminated. |
2796 | * @remark Fails with assertion error if passed UTF-8 is invalid. |
2797 | */ |
2798 | std::wstring windows_utf8_to_wide(const char *str); |
2799 | |
2800 | /** |
2801 | * Converts a wide character string obtained from the Windows API |
2802 | * to a UTF-8 encoded string. |
2803 | * |
2804 | * @ingroup Shell |
2805 | * |
2806 | * @param wide_str The wide character string to convert. |
2807 | * |
2808 | * @return The argument as a UTF-8 encoded string, wrapped in an optional. |
2809 | * The optional is empty, if the wide string contains invalid codepoints. |
2810 | * |
2811 | * @remark The argument string must be zero-terminated. |
2812 | */ |
2813 | std::optional<std::string> windows_wide_to_utf8(const wchar_t *wide_str); |
2814 | |
2815 | /** |
2816 | * This is a RAII wrapper to initialize/uninitialize the Windows COM library, |
2817 | * which may be necessary for using the @link open_file @endlink and |
2818 | * @link open_link @endlink functions. |
2819 | * Must be used on every thread. It's automatically used on threads created |
2820 | * with @link thread_init @endlink. Pass `true` to the constructor on threads |
2821 | * that own a window (i.e. pump a message queue). |
2822 | * |
2823 | * @ingroup Shell |
2824 | */ |
2825 | class CWindowsComLifecycle |
2826 | { |
2827 | public: |
2828 | CWindowsComLifecycle(bool HasWindow); |
2829 | ~CWindowsComLifecycle(); |
2830 | }; |
2831 | |
2832 | /** |
2833 | * Registers a protocol handler. |
2834 | * |
2835 | * @ingroup Shell |
2836 | * |
2837 | * @param protocol_name The name of the protocol. |
2838 | * @param executable The absolute path of the executable that will be associated with the protocol. |
2839 | * @param updated Pointer to a variable that will be set to `true`, iff the shell needs to be updated. |
2840 | * |
2841 | * @return `true` on success, `false` on failure. |
2842 | * |
2843 | * @remark The caller must later call @link shell_update @endlink, iff the shell needs to be updated. |
2844 | */ |
2845 | bool shell_register_protocol(const char *protocol_name, const char *executable, bool *updated); |
2846 | |
2847 | /** |
2848 | * Registers a file extension. |
2849 | * |
2850 | * @ingroup Shell |
2851 | * |
2852 | * @param extension The file extension, including the leading dot. |
2853 | * @param description A readable description for the file extension. |
2854 | * @param executable_name A unique name that will used to describe the application. |
2855 | * @param executable The absolute path of the executable that will be associated with the file extension. |
2856 | * @param updated Pointer to a variable that will be set to `true`, iff the shell needs to be updated. |
2857 | * |
2858 | * @return `true` on success, `false` on failure. |
2859 | * |
2860 | * @remark The caller must later call @link shell_update @endlink, iff the shell needs to be updated. |
2861 | */ |
2862 | bool shell_register_extension(const char *extension, const char *description, const char *executable_name, const char *executable, bool *updated); |
2863 | |
2864 | /** |
2865 | * Registers an application. |
2866 | * |
2867 | * @ingroup Shell |
2868 | * |
2869 | * @param name Readable name of the application. |
2870 | * @param executable The absolute path of the executable being registered. |
2871 | * @param updated Pointer to a variable that will be set to `true`, iff the shell needs to be updated. |
2872 | * |
2873 | * @return `true` on success, `false` on failure. |
2874 | * |
2875 | * @remark The caller must later call @link shell_update @endlink, iff the shell needs to be updated. |
2876 | */ |
2877 | bool shell_register_application(const char *name, const char *executable, bool *updated); |
2878 | |
2879 | /** |
2880 | * Unregisters a protocol or file extension handler. |
2881 | * |
2882 | * @ingroup Shell |
2883 | * |
2884 | * @param shell_class The shell class to delete. |
2885 | * For protocols this is the name of the protocol. |
2886 | * For file extensions this is the program ID associated with the file extension. |
2887 | * @param updated Pointer to a variable that will be set to `true`, iff the shell needs to be updated. |
2888 | * |
2889 | * @return `true` on success, `false` on failure. |
2890 | * |
2891 | * @remark The caller must later call @link shell_update @endlink, iff the shell needs to be updated. |
2892 | */ |
2893 | bool shell_unregister_class(const char *shell_class, bool *updated); |
2894 | |
2895 | /** |
2896 | * Unregisters an application. |
2897 | * |
2898 | * @ingroup Shell |
2899 | * |
2900 | * @param executable The absolute path of the executable being unregistered. |
2901 | * @param updated Pointer to a variable that will be set to `true`, iff the shell needs to be updated. |
2902 | * |
2903 | * @return `true` on success, `false` on failure. |
2904 | * |
2905 | * @remark The caller must later call @link shell_update @endlink, iff the shell needs to be updated. |
2906 | */ |
2907 | bool shell_unregister_application(const char *executable, bool *updated); |
2908 | |
2909 | /** |
2910 | * Notifies the system that a protocol or file extension has been changed and the shell needs to be updated. |
2911 | * |
2912 | * @ingroup Shell |
2913 | * |
2914 | * @remark This is a potentially expensive operation, so it should only be called when necessary. |
2915 | */ |
2916 | void shell_update(); |
2917 | #endif |
2918 | |
2919 | template<> |
2920 | struct std::hash<NETADDR> |
2921 | { |
2922 | size_t operator()(const NETADDR &Addr) const noexcept; |
2923 | }; |
2924 | |
2925 | #endif |
2926 | |