| 1 | #ifndef AWS_COMMON_STRING_H |
| 2 | #define AWS_COMMON_STRING_H |
| 3 | /* |
| 4 | * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| 5 | * |
| 6 | * Licensed under the Apache License, Version 2.0 (the "License"). |
| 7 | * You may not use this file except in compliance with the License. |
| 8 | * A copy of the License is located at |
| 9 | * |
| 10 | * http://aws.amazon.com/apache2.0 |
| 11 | * |
| 12 | * or in the "license" file accompanying this file. This file is distributed |
| 13 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| 14 | * express or implied. See the License for the specific language governing |
| 15 | * permissions and limitations under the License. |
| 16 | */ |
| 17 | #include <aws/common/byte_buf.h> |
| 18 | #include <aws/common/common.h> |
| 19 | |
| 20 | /** |
| 21 | * Represents an immutable string holding either text or binary data. If the |
| 22 | * string is in constant memory or memory that should otherwise not be freed by |
| 23 | * this struct, set allocator to NULL and destroy function will be a no-op. |
| 24 | * |
| 25 | * This is for use cases where the entire struct and the data bytes themselves |
| 26 | * need to be held in dynamic memory, such as when held by a struct |
| 27 | * aws_hash_table. The data bytes themselves are always held in contiguous |
| 28 | * memory immediately after the end of the struct aws_string, and the memory for |
| 29 | * both the header and the data bytes is allocated together. |
| 30 | * |
| 31 | * Use the aws_string_bytes function to access the data bytes. A null byte is |
| 32 | * always included immediately after the data but not counted in the length, so |
| 33 | * that the output of aws_string_bytes can be treated as a C-string in cases |
| 34 | * where none of the the data bytes are null. |
| 35 | * |
| 36 | * Note that the fields of this structure are const; this ensures not only that |
| 37 | * they cannot be modified, but also that you can't assign the structure using |
| 38 | * the = operator accidentally. |
| 39 | */ |
| 40 | |
| 41 | /* Using a flexible array member is the C99 compliant way to have the bytes of |
| 42 | * the string immediately follow the header. |
| 43 | * |
| 44 | * MSVC doesn't know this for some reason so we need to use a pragma to make |
| 45 | * it happy. |
| 46 | */ |
| 47 | #ifdef _MSC_VER |
| 48 | # pragma warning(push) |
| 49 | # pragma warning(disable : 4200) |
| 50 | #endif |
| 51 | struct aws_string { |
| 52 | struct aws_allocator *const allocator; |
| 53 | const size_t len; |
| 54 | const uint8_t bytes[]; |
| 55 | }; |
| 56 | #ifdef _MSC_VER |
| 57 | # pragma warning(pop) |
| 58 | #endif |
| 59 | |
| 60 | AWS_EXTERN_C_BEGIN |
| 61 | |
| 62 | /** |
| 63 | * Returns true if bytes of string are the same, false otherwise. |
| 64 | */ |
| 65 | AWS_COMMON_API |
| 66 | bool aws_string_eq(const struct aws_string *a, const struct aws_string *b); |
| 67 | |
| 68 | /** |
| 69 | * Returns true if bytes of string are equivalent, using a case-insensitive comparison. |
| 70 | */ |
| 71 | AWS_COMMON_API |
| 72 | bool aws_string_eq_ignore_case(const struct aws_string *a, const struct aws_string *b); |
| 73 | |
| 74 | /** |
| 75 | * Returns true if bytes of string and cursor are the same, false otherwise. |
| 76 | */ |
| 77 | AWS_COMMON_API |
| 78 | bool aws_string_eq_byte_cursor(const struct aws_string *str, const struct aws_byte_cursor *cur); |
| 79 | |
| 80 | /** |
| 81 | * Returns true if bytes of string and cursor are equivalent, using a case-insensitive comparison. |
| 82 | */ |
| 83 | AWS_COMMON_API |
| 84 | bool aws_string_eq_byte_cursor_ignore_case(const struct aws_string *str, const struct aws_byte_cursor *cur); |
| 85 | |
| 86 | /** |
| 87 | * Returns true if bytes of string and buffer are the same, false otherwise. |
| 88 | */ |
| 89 | AWS_COMMON_API |
| 90 | bool aws_string_eq_byte_buf(const struct aws_string *str, const struct aws_byte_buf *buf); |
| 91 | |
| 92 | /** |
| 93 | * Returns true if bytes of string and buffer are equivalent, using a case-insensitive comparison. |
| 94 | */ |
| 95 | AWS_COMMON_API |
| 96 | bool aws_string_eq_byte_buf_ignore_case(const struct aws_string *str, const struct aws_byte_buf *buf); |
| 97 | |
| 98 | AWS_COMMON_API |
| 99 | bool aws_string_eq_c_str(const struct aws_string *str, const char *c_str); |
| 100 | |
| 101 | /** |
| 102 | * Returns true if bytes of strings are equivalent, using a case-insensitive comparison. |
| 103 | */ |
| 104 | AWS_COMMON_API |
| 105 | bool aws_string_eq_c_str_ignore_case(const struct aws_string *str, const char *c_str); |
| 106 | |
| 107 | /** |
| 108 | * Constructor functions which copy data from null-terminated C-string or array of bytes. |
| 109 | */ |
| 110 | AWS_COMMON_API |
| 111 | struct aws_string *aws_string_new_from_c_str(struct aws_allocator *allocator, const char *c_str); |
| 112 | AWS_COMMON_API |
| 113 | struct aws_string *aws_string_new_from_array(struct aws_allocator *allocator, const uint8_t *bytes, size_t len); |
| 114 | |
| 115 | /** |
| 116 | * Allocate a new string with the same contents as the old. |
| 117 | */ |
| 118 | AWS_COMMON_API |
| 119 | struct aws_string *aws_string_new_from_string(struct aws_allocator *allocator, const struct aws_string *str); |
| 120 | |
| 121 | /** |
| 122 | * Deallocate string. |
| 123 | */ |
| 124 | AWS_COMMON_API |
| 125 | void aws_string_destroy(struct aws_string *str); |
| 126 | |
| 127 | /** |
| 128 | * Zeroes out the data bytes of string and then deallocates the memory. |
| 129 | * Not safe to run on a string created with AWS_STATIC_STRING_FROM_LITERAL. |
| 130 | */ |
| 131 | AWS_COMMON_API |
| 132 | void aws_string_destroy_secure(struct aws_string *str); |
| 133 | |
| 134 | /** |
| 135 | * Compares lexicographical ordering of two strings. This is a binary |
| 136 | * byte-by-byte comparison, treating bytes as unsigned integers. It is suitable |
| 137 | * for either textual or binary data and is unaware of unicode or any other byte |
| 138 | * encoding. If both strings are identical in the bytes of the shorter string, |
| 139 | * then the longer string is lexicographically after the shorter. |
| 140 | * |
| 141 | * Returns a positive number if string a > string b. (i.e., string a is |
| 142 | * lexicographically after string b.) Returns zero if string a = string b. |
| 143 | * Returns negative number if string a < string b. |
| 144 | */ |
| 145 | AWS_COMMON_API |
| 146 | int aws_string_compare(const struct aws_string *a, const struct aws_string *b); |
| 147 | |
| 148 | /** |
| 149 | * A convenience function for sorting lists of (const struct aws_string *) elements. This can be used as a |
| 150 | * comparator for aws_array_list_sort. It is just a simple wrapper around aws_string_compare. |
| 151 | */ |
| 152 | AWS_COMMON_API |
| 153 | int aws_array_list_comparator_string(const void *a, const void *b); |
| 154 | |
| 155 | /** |
| 156 | * Defines a (static const struct aws_string *) with name specified in first |
| 157 | * argument that points to constant memory and has data bytes containing the |
| 158 | * string literal in the second argument. |
| 159 | * |
| 160 | * GCC allows direct initilization of structs with variable length final fields |
| 161 | * However, this might not be portable, so we can do this instead |
| 162 | * This will have to be updated whenever the aws_string structure changes |
| 163 | */ |
| 164 | #define AWS_STATIC_STRING_FROM_LITERAL(name, literal) \ |
| 165 | static const struct { \ |
| 166 | struct aws_allocator *const allocator; \ |
| 167 | const size_t len; \ |
| 168 | const uint8_t bytes[sizeof(literal)]; \ |
| 169 | } name##_s = {NULL, sizeof(literal) - 1, literal}; \ |
| 170 | static const struct aws_string *(name) = (struct aws_string *)(&name##_s) |
| 171 | |
| 172 | /* |
| 173 | * A related macro that declares the string pointer without static, allowing it to be externed as a global constant |
| 174 | */ |
| 175 | #define AWS_STRING_FROM_LITERAL(name, literal) \ |
| 176 | static const struct { \ |
| 177 | struct aws_allocator *const allocator; \ |
| 178 | const size_t len; \ |
| 179 | const uint8_t bytes[sizeof(literal)]; \ |
| 180 | } name##_s = {NULL, sizeof(literal) - 1, literal}; \ |
| 181 | const struct aws_string *(name) = (struct aws_string *)(&name##_s) |
| 182 | |
| 183 | /** |
| 184 | * Copies all bytes from string to buf. |
| 185 | * |
| 186 | * On success, returns true and updates the buf pointer/length |
| 187 | * accordingly. If there is insufficient space in the buf, returns |
| 188 | * false, leaving the buf unchanged. |
| 189 | */ |
| 190 | AWS_COMMON_API |
| 191 | bool aws_byte_buf_write_from_whole_string( |
| 192 | struct aws_byte_buf *AWS_RESTRICT buf, |
| 193 | const struct aws_string *AWS_RESTRICT src); |
| 194 | |
| 195 | /** |
| 196 | * Creates an aws_byte_cursor from an existing string. |
| 197 | */ |
| 198 | AWS_COMMON_API |
| 199 | struct aws_byte_cursor aws_byte_cursor_from_string(const struct aws_string *src); |
| 200 | |
| 201 | /** |
| 202 | * If the string was dynamically allocated, clones it. If the string was statically allocated (i.e. has no allocator), |
| 203 | * returns the original string. |
| 204 | */ |
| 205 | AWS_COMMON_API |
| 206 | struct aws_string *aws_string_clone_or_reuse(struct aws_allocator *allocator, const struct aws_string *str); |
| 207 | |
| 208 | /* Computes the length of a c string in bytes assuming the character set is either ASCII or UTF-8. If no NULL character |
| 209 | * is found within max_read_len of str, AWS_ERROR_C_STRING_BUFFER_NOT_NULL_TERMINATED is raised. Otherwise, str_len |
| 210 | * will contain the string length minus the NULL character, and AWS_OP_SUCCESS will be returned. */ |
| 211 | AWS_COMMON_API |
| 212 | int aws_secure_strlen(const char *str, size_t max_read_len, size_t *str_len); |
| 213 | |
| 214 | /** |
| 215 | * Equivalent to str->bytes. |
| 216 | */ |
| 217 | AWS_STATIC_IMPL |
| 218 | const uint8_t *aws_string_bytes(const struct aws_string *str); |
| 219 | |
| 220 | /** |
| 221 | * Equivalent to `(const char *)str->bytes`. |
| 222 | */ |
| 223 | AWS_STATIC_IMPL |
| 224 | const char *aws_string_c_str(const struct aws_string *str); |
| 225 | |
| 226 | /** |
| 227 | * Evaluates the set of properties that define the shape of all valid aws_string structures. |
| 228 | * It is also a cheap check, in the sense it run in constant time (i.e., no loops or recursion). |
| 229 | */ |
| 230 | AWS_STATIC_IMPL |
| 231 | bool aws_string_is_valid(const struct aws_string *str); |
| 232 | |
| 233 | /** |
| 234 | * Best-effort checks aws_string invariants, when the str->len is unknown |
| 235 | */ |
| 236 | AWS_STATIC_IMPL |
| 237 | bool aws_c_string_is_valid(const char *str); |
| 238 | |
| 239 | #ifndef AWS_NO_STATIC_IMPL |
| 240 | # include <aws/common/string.inl> |
| 241 | #endif /* AWS_NO_STATIC_IMPL */ |
| 242 | |
| 243 | AWS_EXTERN_C_END |
| 244 | |
| 245 | #endif /* AWS_COMMON_STRING_H */ |
| 246 | |