1 /* vim: set expandtab ts=4 sw=4: */ 2 /* 3 * You may redistribute this program and/or modify it under the terms of 4 * the GNU General Public License as published by the Free Software Foundation, 5 * either version 3 of the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program. If not, see <https://www.gnu.org/licenses/>. 14 */ 15 #ifndef String_H 16 #define String_H 17 18 #include "benc/Object.h" 19 #include "memory/Allocator.h" 20 #include "util/CString.h" 21 #include "util/Linker.h" 22 Linker_require("benc/String.c") 23 24 #include <stdbool.h> 25 #include <stddef.h> // NULL 26 27 /** 28 * Create a new bencoded string from a C null terminated string. 29 * This implementation will make a copy of the string into the memory provided by the allocator. 30 * 31 * @param bytes the beginning of a memory location containing the string to use. 32 * @param allocator a means of getting the memory to store the string object. 33 * @return a bencoded string. 34 */ 35 String* String_new(const char* bytes, struct Allocator* allocator); 36 37 /** 38 * Create a new bencoded constant string on the stack. 39 */ 40 #define String_CONST(x) (&(String) { .bytes = x, .len = CString_strlen(x) }) 41 42 /** For use outside of functions with compile time constant strings. */ 43 #define String_CONST_SO(x) (&(String) { .bytes = x, .len = sizeof(x) - 1 }) 44 45 #define String_OBJ(x) (&(Object) { .type = Object_STRING, .as.string = x }) 46 47 /** 48 * Create a new bencoded string from a set of bytes. 49 * This implementation will make a copy of the string into the memory provided by the allocator. 50 * 51 * @param bytes the beginning of a memory location containing thre string to use. 52 if NULL then this will make a new string of null characters. 53 * @param length the number of bytes to use from the location. 54 * @param allocator a means of getting the memory to store the string object. 55 * @return a bencoded string. 56 */ 57 String* String_newBinary(const char* bytes, uintptr_t length, struct Allocator* allocator); 58 59 #define String_clone(string, alloc) \ 60 ((string) ? String_newBinary(string->bytes, string->len, alloc) : NULL) 61 62 /** 63 * Create a new bencoded string from a format and arguments. 64 * EG: String_printf("this is on line number %d!", allocator, __LINE__); 65 * 66 * @param allocator a means of getting the memory to store the string object. 67 * @param format standard printf formatting. 68 * @params arguments to the printf() function. 69 * @return a bencoded string. 70 */ 71 String* String_printf(struct Allocator* allocator, const char* format, ...); 72 73 #ifdef va_start 74 /** 75 * Same as String_printf() except the arguments are passed as a va_list. 76 * Only enabled if stdarg.h is included before String.h. 77 */ 78 String* String_vprintf(struct Allocator* allocator, const char* format, va_list args); 79 #endif 80 81 /** 82 * Compare 2 bencoded strings. 83 * If the first differing character is numerically smaller for input a then 84 * a negative number is returned, if the first differing character is numerically 85 * smaller for input b then a positive number. If all characters in a and b are 86 * the same then the difference in length (a->len - b->len) is returned. 87 * If a is NULL and b is not NULL then a negative is returned, if b is NULL and a 88 * not NULL then a positive is returned, if both NULL then 0. 89 * 90 * @param a the first string to compare. 91 * @param b the second string to compare. 92 * @return the output from comparison, 0 if and only if they are equal. 93 */ 94 int String_compare(const String* a, const String* b); 95 96 /** 97 * Will return true if and only if the String_compare() would return 0. 98 * 99 * @param a the first string to compare. 100 * @param b the second string to compare. 101 * @return !(String_compare(a, b)) 102 */ 103 int String_equals(const String* a, const String* b); 104 105 #endif 106