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