/* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2019, Joyent, Inc. */ #ifndef _STRVIEW_H #define _STRVIEW_H #include #ifdef __cplusplus extern "C" { #endif /* * strview_t's represent a read-only subset of a string. It is somewhat * similar to the concept of ranges found in other languages in that one can * create a strview_t, and then create a smaller range for iteration. * * sv_first is the address of the first location (and is advanced as values * are consumed) in the string. * * sv_last is the address one byte after the last valid value of the subset. * Basically, the length of the range is equal to 'sv_last - sv_first'. For * example, in the string 'abcdef' to create a view 'bcd', *sv_first would * equal 'b' and *sv_last would equal 'e'. * * sv_rem is the number of bytes remaining in the range. * * A strview_t maintains references to the underlying string, so the lifetime * of a strview_t should be equal to or less than the underlying string (i.e. * it doesn't copy the data from the underlying string, but maintains pointers * to the original data). * * While the underlying string does not need to be NUL-terminated, NUL is still * used as a sentinel value in some instances (e.g. sv_peek()), and should not * be contained within the defined range. * * As hinted above, the functions currently do not deal with multi-byte * characters, i.e. each character is assumed to be a single byte. The * current consumers do not need to handle multi-byte characters (UTF-8 * or otherwise), so this is sufficient at the current time. */ typedef struct strview { const char *sv_first; const char *sv_last; size_t sv_rem; } strview_t; /* * SV_PRINT() is used for printing strview_t values during debugging, e.g. * `DEMDEBUG("%*.s", SV_PRINT(sv));` */ #define SV_PRINT(_sv) (int)(_sv)->sv_rem, (_sv)->sv_first /* * Initialize a strview_t from an already initialized strview_t -- the state of * the source strview_t is duplicated in the newly initialized strview_t. */ void sv_init_sv(strview_t *, const strview_t *); /* * Initialize a strview_t as a subset of an already initialized strview_t. * The size of the subset (size_t) must be <= sv_remaining(src). */ void sv_init_sv_range(strview_t *, const strview_t *, size_t); /* * Initialize a strview_t from a string. The two const char * pointers are the * sv_first and sv_last values to use (see above). If the source string is * NUL-terminated, one can optionally pass NULL for the second parameter in * which case, the entire NUL-terminated string (starting at sv_first) is * treated as a strview_t. */ void sv_init_str(strview_t *, const char *, const char *); /* * Return the number of bytes remaining to consume in the strview_t */ size_t sv_remaining(const strview_t *); /* * Return the char at the given position in the strview_t (without advancing * the position). Position values >=0 are relative to the current position * of the strview_t (e.g. '0' will return the next character, '1' will return * the character after that), while negative position values are relative to * the end of the strview_t (e.g. '-1' will return the last character, '-2' * will return the second to last character). * * If the position value is out of range, '\0' is returned. */ char sv_peek(const strview_t *, ssize_t); /* * Return the next character and advance the strview_t position. If no more * characters are available, '\0' is returned. */ char sv_consume_c(strview_t *); /* * Advance the position of the strview_t by the given number of bytes. The * amount must be <= the number of bytes remaining in the strview_t. */ void sv_consume_n(strview_t *, size_t); /* * Advance the strview_t position if the bytes of the strview starting at the * current position match the given NUL-terminated string. The length of the * NUL-terminated string must be <= the number of bytes remaining in the * strview_t. * * If there is a match, the position of the strview_t is advanced by the * length of the NUL-terminated comparison string, and B_TRUE is returned. If * there is no match, the position is not advanced and B_FALSE is returned. */ boolean_t sv_consume_if(strview_t *, const char *); /* * Advance the position of the strview_t if the next char in the strview_t * is equal to the given char. If there is a match, the strview_t position * is advanced one byte and B_TRUE is returned. If they do not match, B_FALSE * is returned and the position is not advanced. */ boolean_t sv_consume_if_c(strview_t *, char); #ifdef __cplusplus } #endif #endif /* _STRVIEW_H */