X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fencoding.c;h=5ff1df2312d906cb1f560a7aa9a756e12efaaa21;hb=ccaeb7b1b39754f82a084ff7d9307962d8142339;hp=b54e787bd4cc10a5b671146dbad7661b5e9101bc;hpb=3071e89c11d1be71cf45b694432e5908e0c4ded9;p=wimlib diff --git a/src/encoding.c b/src/encoding.c index b54e787b..5ff1df23 100644 --- a/src/encoding.c +++ b/src/encoding.c @@ -23,7 +23,13 @@ # include "config.h" #endif +#include +#include +#include +#include + #include "wimlib.h" +#include "wimlib/alloca.h" #include "wimlib/assert.h" #include "wimlib/encoding.h" #include "wimlib/endianness.h" @@ -31,15 +37,6 @@ #include "wimlib/list.h" #include "wimlib/util.h" -#include -#include -#include -#include -#include - -#ifdef HAVE_ALLOCA_H -# include -#endif bool wimlib_mbs_is_utf8 = !TCHAR_IS_UTF16LE; @@ -139,7 +136,7 @@ varname1##_to_##varname2##_nbytes(const chartype1 *in, size_t in_nbytes,\ bool buf_onheap; \ bufsize = (worst_case_len_expr) * sizeof(chartype2); \ /* Worst case length */ \ - if (bufsize <= STACK_MAX) { \ + if (bufsize <= STACK_MAX) { \ buf = alloca(bufsize); \ buf_onheap = false; \ } else { \ @@ -561,9 +558,35 @@ cmp_utf16le_strings(const utf16lechar *s1, size_t n1, return (n1 < n2) ? -1 : 1; } -/* Duplicate a UTF16-LE string which may not be null-terminated. */ +/* Like cmp_utf16le_strings(), but assumes the strings are null terminated. */ +int +cmp_utf16le_strings_z(const utf16lechar *s1, const utf16lechar *s2, + bool ignore_case) +{ + if (ignore_case) { + for (;;) { + u16 c1 = upcase[le16_to_cpu(*s1)]; + u16 c2 = upcase[le16_to_cpu(*s2)]; + if (c1 != c2) + return (c1 < c2) ? -1 : 1; + if (c1 == 0) + return 0; + s1++, s2++; + } + } else { + while (*s1 && *s1 == *s2) + s1++, s2++; + if (*s1 == *s2) + return 0; + return (le16_to_cpu(*s1) < le16_to_cpu(*s2)) ? -1 : 1; + } +} + +/* Duplicate a UTF-16LE string. The input string might not be null terminated + * and might be misaligned, but the returned string is guaranteed to be null + * terminated and properly aligned. */ utf16lechar * -utf16le_dupz(const utf16lechar *ustr, size_t usize) +utf16le_dupz(const void *ustr, size_t usize) { utf16lechar *dup = MALLOC(usize + sizeof(utf16lechar)); if (dup) { @@ -572,3 +595,32 @@ utf16le_dupz(const utf16lechar *ustr, size_t usize) } return dup; } + +/* Duplicate a null-terminated UTF-16LE string. */ +utf16lechar * +utf16le_dup(const utf16lechar *ustr) +{ + const utf16lechar *p = ustr; + while (*p++) + ; + return memdup(ustr, (const u8 *)p - (const u8 *)ustr); +} + +/* Return the length, in bytes, of a UTF-null terminated UTF-16 string, + * excluding the null terminator. */ +size_t +utf16le_len_bytes(const utf16lechar *s) +{ + const utf16lechar *p = s; + while (*p) + p++; + return (p - s) * sizeof(utf16lechar); +} + +/* Return the length, in UTF-16 coding units, of a UTF-null terminated UTF-16 + * string, excluding the null terminator. */ +size_t +utf16le_len_chars(const utf16lechar *s) +{ + return utf16le_len_bytes(s) / sizeof(utf16lechar); +}