1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2019, Joyent, Inc. 14 */ 15 16 #ifndef _STRVIEW_H 17 #define _STRVIEW_H 18 19 #include <inttypes.h> 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 /* 26 * strview_t's represent a read-only subset of a string. It is somewhat 27 * similar to the concept of ranges found in other languages in that one can 28 * create a strview_t, and then create a smaller range for iteration. 29 * 30 * sv_first is the address of the first location (and is advanced as values 31 * are consumed) in the string. 32 * 33 * sv_last is the address one byte after the last valid value of the subset. 34 * Basically, the length of the range is equal to 'sv_last - sv_first'. For 35 * example, in the string 'abcdef' to create a view 'bcd', *sv_first would 36 * equal 'b' and *sv_last would equal 'e'. 37 * 38 * sv_rem is the number of bytes remaining in the range. 39 * 40 * A strview_t maintains references to the underlying string, so the lifetime 41 * of a strview_t should be equal to or less than the underlying string (i.e. 42 * it doesn't copy the data from the underlying string, but maintains pointers 43 * to the original data). 44 * 45 * While the underlying string does not need to be NUL-terminated, NUL is still 46 * used as a sentinel value in some instances (e.g. sv_peek()), and should not 47 * be contained within the defined range. 48 * 49 * As hinted above, the functions currently do not deal with multi-byte 50 * characters, i.e. each character is assumed to be a single byte. The 51 * current consumers do not need to handle multi-byte characters (UTF-8 52 * or otherwise), so this is sufficient at the current time. 53 */ 54 typedef struct strview { 55 const char *sv_first; 56 const char *sv_last; 57 size_t sv_rem; 58 } strview_t; 59 60 /* 61 * SV_PRINT() is used for printing strview_t values during debugging, e.g. 62 * `DEMDEBUG("%*.s", SV_PRINT(sv));` 63 */ 64 #define SV_PRINT(_sv) (int)(_sv)->sv_rem, (_sv)->sv_first 65 66 /* 67 * Initialize a strview_t from an already initialized strview_t -- the state of 68 * the source strview_t is duplicated in the newly initialized strview_t. 69 */ 70 void sv_init_sv(strview_t *, const strview_t *); 71 72 /* 73 * Initialize a strview_t as a subset of an already initialized strview_t. 74 * The size of the subset (size_t) must be <= sv_remaining(src). 75 */ 76 void sv_init_sv_range(strview_t *, const strview_t *, size_t); 77 78 /* 79 * Initialize a strview_t from a string. The two const char * pointers are the 80 * sv_first and sv_last values to use (see above). If the source string is 81 * NUL-terminated, one can optionally pass NULL for the second parameter in 82 * which case, the entire NUL-terminated string (starting at sv_first) is 83 * treated as a strview_t. 84 */ 85 void sv_init_str(strview_t *, const char *, const char *); 86 87 /* 88 * Return the number of bytes remaining to consume in the strview_t 89 */ 90 size_t sv_remaining(const strview_t *); 91 92 /* 93 * Return the char at the given position in the strview_t (without advancing 94 * the position). Position values >=0 are relative to the current position 95 * of the strview_t (e.g. '0' will return the next character, '1' will return 96 * the character after that), while negative position values are relative to 97 * the end of the strview_t (e.g. '-1' will return the last character, '-2' 98 * will return the second to last character). 99 * 100 * If the position value is out of range, '\0' is returned. 101 */ 102 char sv_peek(const strview_t *, ssize_t); 103 104 /* 105 * Return the next character and advance the strview_t position. If no more 106 * characters are available, '\0' is returned. 107 */ 108 char sv_consume_c(strview_t *); 109 110 /* 111 * Advance the position of the strview_t by the given number of bytes. The 112 * amount must be <= the number of bytes remaining in the strview_t. 113 */ 114 void sv_consume_n(strview_t *, size_t); 115 116 /* 117 * Advance the strview_t position if the bytes of the strview starting at the 118 * current position match the given NUL-terminated string. The length of the 119 * NUL-terminated string must be <= the number of bytes remaining in the 120 * strview_t. 121 * 122 * If there is a match, the position of the strview_t is advanced by the 123 * length of the NUL-terminated comparison string, and B_TRUE is returned. If 124 * there is no match, the position is not advanced and B_FALSE is returned. 125 */ 126 boolean_t sv_consume_if(strview_t *, const char *); 127 128 /* 129 * Advance the position of the strview_t if the next char in the strview_t 130 * is equal to the given char. If there is a match, the strview_t position 131 * is advanced one byte and B_TRUE is returned. If they do not match, B_FALSE 132 * is returned and the position is not advanced. 133 */ 134 boolean_t sv_consume_if_c(strview_t *, char); 135 136 #ifdef __cplusplus 137 } 138 #endif 139 140 #endif /* _STRVIEW_H */ 141