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