/* lowercasing/casefolding in C locale */
static size_t
-strlower_c(char *dst, size_t dstsize, const char *src, ssize_t srclen)
+strlower_c(char *dst, size_t dstsize, const char *src, size_t srclen)
{
int i;
- srclen = (srclen >= 0) ? srclen : strlen(src);
for (i = 0; i < srclen && i < dstsize; i++)
dst[i] = pg_ascii_tolower(src[i]);
if (i < dstsize)
/* titlecasing in C locale */
static size_t
-strtitle_c(char *dst, size_t dstsize, const char *src, ssize_t srclen)
+strtitle_c(char *dst, size_t dstsize, const char *src, size_t srclen)
{
bool wasalnum = false;
int i;
- srclen = (srclen >= 0) ? srclen : strlen(src);
for (i = 0; i < srclen && i < dstsize; i++)
{
char c = src[i];
/* uppercasing in C locale */
static size_t
-strupper_c(char *dst, size_t dstsize, const char *src, ssize_t srclen)
+strupper_c(char *dst, size_t dstsize, const char *src, size_t srclen)
{
int i;
- srclen = (srclen >= 0) ? srclen : strlen(src);
for (i = 0; i < srclen && i < dstsize; i++)
dst[i] = pg_ascii_toupper(src[i]);
if (i < dstsize)
}
size_t
-pg_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+pg_strlower(char *dst, size_t dstsize, const char *src, size_t srclen,
pg_locale_t locale)
{
if (locale->ctype == NULL)
}
size_t
-pg_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+pg_strtitle(char *dst, size_t dstsize, const char *src, size_t srclen,
pg_locale_t locale)
{
if (locale->ctype == NULL)
}
size_t
-pg_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+pg_strupper(char *dst, size_t dstsize, const char *src, size_t srclen,
pg_locale_t locale)
{
if (locale->ctype == NULL)
}
size_t
-pg_strfold(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+pg_strfold(char *dst, size_t dstsize, const char *src, size_t srclen,
pg_locale_t locale)
{
/* in the C locale, casefolding is the same as lowercasing */
* pg_strfold(..., default_locale)?
*/
size_t
-pg_downcase_ident(char *dst, size_t dstsize, const char *src, ssize_t srclen)
+pg_downcase_ident(char *dst, size_t dstsize, const char *src, size_t srclen)
{
pg_locale_t locale = default_locale;
int
pg_strcoll(const char *arg1, const char *arg2, pg_locale_t locale)
{
- return locale->collate->strncoll(arg1, -1, arg2, -1, locale);
+ return locale->collate->strcoll(arg1, arg2, locale);
}
/*
* appropriate for the given locale, platform, and database encoding. If the
* locale is not specified, use the database collation.
*
- * The input strings must be encoded in the database encoding. If an input
- * string is NUL-terminated, its length may be specified as -1.
+ * The input strings must be encoded in the database encoding.
*
* The caller is responsible for breaking ties if the collation is
* deterministic; this maintains consistency with pg_strnxfrm(), which cannot
* easily account for deterministic collations.
*/
int
-pg_strncoll(const char *arg1, ssize_t len1, const char *arg2, ssize_t len2,
+pg_strncoll(const char *arg1, size_t len1, const char *arg2, size_t len2,
pg_locale_t locale)
{
return locale->collate->strncoll(arg1, len1, arg2, len2, locale);
size_t
pg_strxfrm(char *dest, const char *src, size_t destsize, pg_locale_t locale)
{
- return locale->collate->strnxfrm(dest, destsize, src, -1, locale);
+ return locale->collate->strxfrm(dest, destsize, src, locale);
}
/*
* ordinary strcmp() on transformed strings is equivalent to pg_strcoll() on
* untransformed strings.
*
- * The input string must be encoded in the database encoding. If the input
- * string is NUL-terminated, its length may be specified as -1. If 'destsize'
- * is zero, 'dest' may be NULL.
+ * The input string must be encoded in the database encoding. If 'destsize' is
+ * zero, 'dest' may be NULL.
*
* Not all providers support pg_strnxfrm() safely. The caller should check
* pg_strxfrm_enabled() first, otherwise this function may return wrong
* 'destsize' or greater, the resulting contents of 'dest' are undefined.
*/
size_t
-pg_strnxfrm(char *dest, size_t destsize, const char *src, ssize_t srclen,
+pg_strnxfrm(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
return locale->collate->strnxfrm(dest, destsize, src, srclen, locale);
pg_strxfrm_prefix(char *dest, const char *src, size_t destsize,
pg_locale_t locale)
{
- return locale->collate->strnxfrm_prefix(dest, destsize, src, -1, locale);
+ return locale->collate->strxfrm_prefix(dest, destsize, src, locale);
}
/*
* memcmp() on the byte sequence is equivalent to pg_strncoll() on
* untransformed strings. The result is not nul-terminated.
*
- * The input string must be encoded in the database encoding. If the input
- * string is NUL-terminated, its length may be specified as -1.
+ * The input string must be encoded in the database encoding.
*
* Not all providers support pg_strnxfrm_prefix() safely. The caller should
* check pg_strxfrm_prefix_enabled() first, otherwise this function may return
*/
size_t
pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
- ssize_t srclen, pg_locale_t locale)
+ size_t srclen, pg_locale_t locale)
{
return locale->collate->strnxfrm_prefix(dest, destsize, src, srclen, locale);
}
{
struct WordBoundaryState *wbstate = (struct WordBoundaryState *) state;
- while (wbstate->offset < wbstate->len &&
- wbstate->str[wbstate->offset] != '\0')
+ while (wbstate->offset < wbstate->len)
{
char32_t u = utf8_to_unicode((const unsigned char *) wbstate->str +
wbstate->offset);
}
static size_t
-strlower_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strlower_builtin(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
return unicode_strlower(dest, destsize, src, srclen,
}
static size_t
-strtitle_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strtitle_builtin(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
struct WordBoundaryState wbstate = {
.str = src,
- .len = (srclen < 0) ? strlen(src) : srclen,
+ .len = srclen,
.offset = 0,
.posix = !locale->builtin.casemap_full,
.init = false,
}
static size_t
-strupper_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strupper_builtin(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
return unicode_strupper(dest, destsize, src, srclen,
}
static size_t
-strfold_builtin(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strfold_builtin(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
return unicode_strfold(dest, destsize, src, srclen,
static UCaseMap *pg_ucasemap_open(const char *loc_str);
static size_t strlower_icu(char *dest, size_t destsize, const char *src,
- ssize_t srclen, pg_locale_t locale);
+ size_t srclen, pg_locale_t locale);
static size_t strtitle_icu(char *dest, size_t destsize, const char *src,
- ssize_t srclen, pg_locale_t locale);
+ size_t srclen, pg_locale_t locale);
static size_t strupper_icu(char *dest, size_t destsize, const char *src,
- ssize_t srclen, pg_locale_t locale);
+ size_t srclen, pg_locale_t locale);
static size_t strfold_icu(char *dest, size_t destsize, const char *src,
- ssize_t srclen, pg_locale_t locale);
+ size_t srclen, pg_locale_t locale);
static size_t strlower_icu_utf8(char *dest, size_t destsize, const char *src,
- ssize_t srclen, pg_locale_t locale);
+ size_t srclen, pg_locale_t locale);
static size_t strtitle_icu_utf8(char *dest, size_t destsize, const char *src,
- ssize_t srclen, pg_locale_t locale);
+ size_t srclen, pg_locale_t locale);
static size_t strupper_icu_utf8(char *dest, size_t destsize, const char *src,
- ssize_t srclen, pg_locale_t locale);
+ size_t srclen, pg_locale_t locale);
static size_t strfold_icu_utf8(char *dest, size_t destsize, const char *src,
- ssize_t srclen, pg_locale_t locale);
+ size_t srclen, pg_locale_t locale);
static size_t downcase_ident_icu(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, pg_locale_t locale);
-static int strncoll_icu(const char *arg1, ssize_t len1,
- const char *arg2, ssize_t len2,
+ size_t srclen, pg_locale_t locale);
+static int strncoll_icu(const char *arg1, size_t len1,
+ const char *arg2, size_t len2,
pg_locale_t locale);
+static int strcoll_icu(const char *arg1, const char *arg2,
+ pg_locale_t locale);
static size_t strnxfrm_icu(char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
+static size_t strxfrm_icu(char *dest, size_t destsize, const char *src,
+ pg_locale_t locale);
extern char *get_collation_actual_version_icu(const char *collcollate);
typedef int32_t (*ICU_Convert_Func) (UChar *dest, int32_t destCapacity,
static UCollator *make_icu_collator(const char *iculocstr,
const char *icurules);
-static int strncoll_icu(const char *arg1, ssize_t len1,
- const char *arg2, ssize_t len2,
- pg_locale_t locale);
static size_t strnxfrm_prefix_icu(char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
+static size_t strxfrm_prefix_icu(char *dest, size_t destsize, const char *src,
+ pg_locale_t locale);
#ifdef HAVE_UCOL_STRCOLLUTF8
-static int strncoll_icu_utf8(const char *arg1, ssize_t len1,
- const char *arg2, ssize_t len2,
+static int strncoll_icu_utf8(const char *arg1, size_t len1,
+ const char *arg2, size_t len2,
pg_locale_t locale);
+static int strcoll_icu_utf8(const char *arg1,
+ const char *arg2,
+ pg_locale_t locale);
#endif
static size_t strnxfrm_prefix_icu_utf8(char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
+static size_t strxfrm_prefix_icu_utf8(char *dest, size_t destsize, const char *src,
+ pg_locale_t locale);
static void init_icu_converter(void);
static int32_t uchar_length(UConverter *converter,
const char *str, int32_t len);
UErrorCode *status);
static int32_t icu_convert_case(ICU_Convert_Func func, char *dest,
size_t destsize, const char *src,
- ssize_t srclen, pg_locale_t locale);
+ size_t srclen, pg_locale_t locale);
static int32_t u_strToTitle_default_BI(UChar *dest, int32_t destCapacity,
const UChar *src, int32_t srcLength,
const char *locale,
static const struct collate_methods collate_methods_icu = {
.strncoll = strncoll_icu,
+ .strcoll = strcoll_icu,
.strnxfrm = strnxfrm_icu,
+ .strxfrm = strxfrm_icu,
.strnxfrm_prefix = strnxfrm_prefix_icu,
+ .strxfrm_prefix = strxfrm_prefix_icu,
.strxfrm_is_safe = true,
};
static const struct collate_methods collate_methods_icu_utf8 = {
#ifdef HAVE_UCOL_STRCOLLUTF8
.strncoll = strncoll_icu_utf8,
+ .strcoll = strcoll_icu_utf8,
#else
.strncoll = strncoll_icu,
+ .strcoll = strcoll_icu,
#endif
.strnxfrm = strnxfrm_icu,
+ .strxfrm = strxfrm_icu,
.strnxfrm_prefix = strnxfrm_prefix_icu_utf8,
+ .strxfrm_prefix = strxfrm_prefix_icu_utf8,
.strxfrm_is_safe = true,
};
}
static size_t
-strlower_icu(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strlower_icu(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
return icu_convert_case(u_strToLower, dest, destsize, src, srclen, locale);
}
static size_t
-strtitle_icu(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strtitle_icu(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
return icu_convert_case(u_strToTitle_default_BI, dest, destsize, src, srclen, locale);
}
static size_t
-strupper_icu(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strupper_icu(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
return icu_convert_case(u_strToUpper, dest, destsize, src, srclen, locale);
}
static size_t
-strfold_icu(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strfold_icu(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
return icu_convert_case(u_strFoldCase_default, dest, destsize, src, srclen, locale);
}
static size_t
-strlower_icu_utf8(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strlower_icu_utf8(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
UErrorCode status = U_ZERO_ERROR;
}
static size_t
-strtitle_icu_utf8(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strtitle_icu_utf8(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
UErrorCode status = U_ZERO_ERROR;
}
static size_t
-strupper_icu_utf8(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strupper_icu_utf8(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
UErrorCode status = U_ZERO_ERROR;
}
static size_t
-strfold_icu_utf8(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strfold_icu_utf8(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
UErrorCode status = U_ZERO_ERROR;
*/
static size_t
downcase_ident_icu(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, pg_locale_t locale)
+ size_t srclen, pg_locale_t locale)
{
int i;
bool libc_lower;
* strncoll_icu_utf8
*
* Call ucol_strcollUTF8() or ucol_strcoll() as appropriate for the given
- * database encoding. An argument length of -1 means the string is
- * NUL-terminated.
+ * database encoding.
*/
#ifdef HAVE_UCOL_STRCOLLUTF8
int
-strncoll_icu_utf8(const char *arg1, ssize_t len1, const char *arg2, ssize_t len2,
+strncoll_icu_utf8(const char *arg1, size_t len1, const char *arg2, size_t len2,
pg_locale_t locale)
{
int result;
return result;
}
+
+int
+strcoll_icu_utf8(const char *arg1, const char *arg2, pg_locale_t locale)
+{
+ int result;
+ UErrorCode status;
+
+ Assert(GetDatabaseEncoding() == PG_UTF8);
+
+ status = U_ZERO_ERROR;
+ result = ucol_strcollUTF8(locale->icu.ucol,
+ arg1, -1,
+ arg2, -1,
+ &status);
+ if (U_FAILURE(status))
+ ereport(ERROR,
+ (errmsg("collation failed: %s", u_errorName(status))));
+
+ return result;
+}
#endif
-/* 'srclen' of -1 means the strings are NUL-terminated */
-size_t
-strnxfrm_icu(char *dest, size_t destsize, const char *src, ssize_t srclen,
- pg_locale_t locale)
+static size_t
+strnxfrm_icu_internal(char *dest, size_t destsize, const char *src, ssize_t srclen,
+ pg_locale_t locale)
{
UChar sbuf[TEXTBUFLEN / sizeof(UChar)];
UChar *uchar = sbuf;
return result_bsize;
}
-/* 'srclen' of -1 means the strings are NUL-terminated */
-size_t
-strnxfrm_prefix_icu_utf8(char *dest, size_t destsize,
- const char *src, ssize_t srclen,
- pg_locale_t locale)
+static size_t
+strnxfrm_icu(char *dest, size_t destsize, const char *src, size_t srclen,
+ pg_locale_t locale)
+{
+ return strnxfrm_icu_internal(dest, destsize, src, srclen, locale);
+}
+
+static size_t
+strxfrm_icu(char *dest, size_t destsize, const char *src,
+ pg_locale_t locale)
+{
+ return strnxfrm_icu_internal(dest, destsize, src, -1, locale);
+}
+
+static size_t
+strnxfrm_prefix_icu_utf8_internal(char *dest, size_t destsize,
+ const char *src, ssize_t srclen,
+ pg_locale_t locale)
{
size_t result;
UCharIterator iter;
return result;
}
+static size_t
+strnxfrm_prefix_icu_utf8(char *dest, size_t destsize,
+ const char *src, size_t srclen,
+ pg_locale_t locale)
+{
+ return strnxfrm_prefix_icu_utf8_internal(dest, destsize, src, srclen, locale);
+}
+
+static size_t
+strxfrm_prefix_icu_utf8(char *dest, size_t destsize, const char *src,
+ pg_locale_t locale)
+{
+ return strnxfrm_prefix_icu_utf8_internal(dest, destsize, src, -1, locale);
+}
+
char *
get_collation_actual_version_icu(const char *collcollate)
{
static int32_t
icu_convert_case(ICU_Convert_Func func, char *dest, size_t destsize,
- const char *src, ssize_t srclen, pg_locale_t locale)
+ const char *src, size_t srclen, pg_locale_t locale)
{
int32_t len_uchar;
int32_t len_conv;
* strncoll_icu
*
* Convert the arguments from the database encoding to UChar strings, then
- * call ucol_strcoll(). An argument length of -1 means that the string is
- * NUL-terminated.
+ * call ucol_strcoll().
*
* When the database encoding is UTF-8, and ICU supports ucol_strcollUTF8(),
* caller should call that instead.
*/
static int
-strncoll_icu(const char *arg1, ssize_t len1,
- const char *arg2, ssize_t len2, pg_locale_t locale)
+strncoll_icu_internal(const char *arg1, ssize_t len1,
+ const char *arg2, ssize_t len2,
+ pg_locale_t locale)
{
UChar sbuf[TEXTBUFLEN / sizeof(UChar)];
UChar *buf = sbuf;
return result;
}
-/* 'srclen' of -1 means the strings are NUL-terminated */
+static int
+strncoll_icu(const char *arg1, size_t len1, const char *arg2, size_t len2,
+ pg_locale_t locale)
+{
+ return strncoll_icu_internal(arg1, len1, arg2, len2, locale);
+}
+
+static int
+strcoll_icu(const char *arg1, const char *arg2, pg_locale_t locale)
+{
+ return strncoll_icu_internal(arg1, -1, arg2, -1, locale);
+}
+
static size_t
-strnxfrm_prefix_icu(char *dest, size_t destsize,
- const char *src, ssize_t srclen,
- pg_locale_t locale)
+strnxfrm_prefix_icu_internal(char *dest, size_t destsize,
+ const char *src, ssize_t srclen,
+ pg_locale_t locale)
{
UChar sbuf[TEXTBUFLEN / sizeof(UChar)];
UChar *uchar = sbuf;
return result_bsize;
}
+static size_t
+strnxfrm_prefix_icu(char *dest, size_t destsize, const char *src, size_t srclen,
+ pg_locale_t locale)
+{
+ return strnxfrm_prefix_icu_internal(dest, destsize, src, srclen, locale);
+}
+
+static size_t
+strxfrm_prefix_icu(char *dest, size_t destsize, const char *src,
+ pg_locale_t locale)
+{
+ return strnxfrm_prefix_icu_internal(dest, destsize, src, -1, locale);
+}
+
static void
init_icu_converter(void)
{
extern pg_locale_t create_pg_locale_libc(Oid collid, MemoryContext context);
-static int strncoll_libc(const char *arg1, ssize_t len1,
- const char *arg2, ssize_t len2,
+static int strncoll_libc(const char *arg1, size_t len1,
+ const char *arg2, size_t len2,
pg_locale_t locale);
+static int strcoll_libc(const char *arg1, const char *arg2,
+ pg_locale_t locale);
static size_t strnxfrm_libc(char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
+static size_t strxfrm_libc(char *dest, size_t destsize,
+ const char *src, pg_locale_t locale);
extern char *get_collation_actual_version_libc(const char *collcollate);
static locale_t make_libc_collator(const char *collate,
const char *ctype);
#ifdef WIN32
-static int strncoll_libc_win32_utf8(const char *arg1, ssize_t len1,
- const char *arg2, ssize_t len2,
+static int strncoll_libc_win32_utf8(const char *arg1, size_t len1,
+ const char *arg2, size_t len2,
pg_locale_t locale);
+static int strcoll_libc_win32_utf8(const char *arg1, const char *arg2,
+ pg_locale_t locale);
#endif
static size_t char2wchar(wchar_t *to, size_t tolen, const char *from,
size_t fromlen, locale_t loc);
static size_t strlower_libc_sb(char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
static size_t strlower_libc_mb(char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
static size_t strtitle_libc_sb(char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
static size_t strtitle_libc_mb(char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
static size_t strupper_libc_sb(char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
static size_t strupper_libc_mb(char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
static bool
*/
static size_t
downcase_ident_libc_sb(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, pg_locale_t locale)
+ size_t srclen, pg_locale_t locale)
{
locale_t loc = locale->lt;
int i;
static const struct collate_methods collate_methods_libc = {
.strncoll = strncoll_libc,
+ .strcoll = strcoll_libc,
.strnxfrm = strnxfrm_libc,
+ .strxfrm = strxfrm_libc,
.strnxfrm_prefix = NULL,
+ .strxfrm_prefix = NULL,
/*
* Unfortunately, it seems that strxfrm() for non-C collations is broken
#ifdef WIN32
static const struct collate_methods collate_methods_libc_win32_utf8 = {
.strncoll = strncoll_libc_win32_utf8,
+ .strcoll = strcoll_libc_win32_utf8,
.strnxfrm = strnxfrm_libc,
+ .strxfrm = strxfrm_libc,
.strnxfrm_prefix = NULL,
#ifdef TRUST_STRXFRM
.strxfrm_is_safe = true,
#endif
static size_t
-strlower_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strlower_libc_sb(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
- if (srclen < 0)
- srclen = strlen(src);
-
if (srclen + 1 <= destsize)
{
locale_t loc = locale->lt;
}
static size_t
-strlower_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strlower_libc_mb(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
locale_t loc = locale->lt;
size_t curr_char;
size_t max_size;
- if (srclen < 0)
- srclen = strlen(src);
-
/* Overflow paranoia */
if ((srclen + 1) > (INT_MAX / sizeof(wchar_t)))
ereport(ERROR,
}
static size_t
-strtitle_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strtitle_libc_sb(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
- if (srclen < 0)
- srclen = strlen(src);
-
if (srclen + 1 <= destsize)
{
locale_t loc = locale->lt;
}
static size_t
-strtitle_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strtitle_libc_mb(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
locale_t loc = locale->lt;
size_t curr_char;
size_t max_size;
- if (srclen < 0)
- srclen = strlen(src);
-
/* Overflow paranoia */
if ((srclen + 1) > (INT_MAX / sizeof(wchar_t)))
ereport(ERROR,
}
static size_t
-strupper_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strupper_libc_sb(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
- if (srclen < 0)
- srclen = strlen(src);
-
if (srclen + 1 <= destsize)
{
locale_t loc = locale->lt;
}
static size_t
-strupper_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen,
+strupper_libc_mb(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
locale_t loc = locale->lt;
size_t curr_char;
size_t max_size;
- if (srclen < 0)
- srclen = strlen(src);
-
/* Overflow paranoia */
if ((srclen + 1) > (INT_MAX / sizeof(wchar_t)))
ereport(ERROR,
/*
* strncoll_libc
*
- * NUL-terminate arguments, if necessary, and pass to strcoll_l().
- *
- * An input string length of -1 means that it's already NUL-terminated.
+ * NUL-terminate arguments and pass to strcoll_l().
*/
-int
-strncoll_libc(const char *arg1, ssize_t len1, const char *arg2, ssize_t len2,
+static int
+strncoll_libc(const char *arg1, size_t len1, const char *arg2, size_t len2,
pg_locale_t locale)
{
char sbuf[TEXTBUFLEN];
char *buf = sbuf;
- size_t bufsize1 = (len1 == -1) ? 0 : len1 + 1;
- size_t bufsize2 = (len2 == -1) ? 0 : len2 + 1;
+ size_t bufsize1 = len1 + 1;
+ size_t bufsize2 = len2 + 1;
+ char *buf1;
+ char *buf2;
const char *arg1n;
const char *arg2n;
int result;
if (bufsize1 + bufsize2 > TEXTBUFLEN)
buf = palloc(bufsize1 + bufsize2);
- /* nul-terminate arguments if necessary */
- if (len1 == -1)
- {
- arg1n = arg1;
- }
- else
- {
- char *buf1 = buf;
-
- memcpy(buf1, arg1, len1);
- buf1[len1] = '\0';
- arg1n = buf1;
- }
+ buf1 = buf;
+ buf2 = buf + bufsize1;
- if (len2 == -1)
- {
- arg2n = arg2;
- }
- else
- {
- char *buf2 = buf + bufsize1;
+ memcpy(buf1, arg1, len1);
+ buf1[len1] = '\0';
+ arg1n = buf1;
- memcpy(buf2, arg2, len2);
- buf2[len2] = '\0';
- arg2n = buf2;
- }
+ memcpy(buf2, arg2, len2);
+ buf2[len2] = '\0';
+ arg2n = buf2;
result = strcoll_l(arg1n, arg2n, locale->lt);
return result;
}
+/*
+ * strcoll_libc
+ */
+static int
+strcoll_libc(const char *arg1, const char *arg2, pg_locale_t locale)
+{
+ return strcoll_l(arg1, arg2, locale->lt);
+}
+
/*
* strnxfrm_libc
*
- * NUL-terminate src, if necessary, and pass to strxfrm_l().
- *
- * A source length of -1 means that it's already NUL-terminated.
+ * NUL-terminate src and pass to strxfrm_l().
*/
-size_t
-strnxfrm_libc(char *dest, size_t destsize, const char *src, ssize_t srclen,
+static size_t
+strnxfrm_libc(char *dest, size_t destsize, const char *src, size_t srclen,
pg_locale_t locale)
{
char sbuf[TEXTBUFLEN];
size_t bufsize = srclen + 1;
size_t result;
- if (srclen == -1)
- return strxfrm_l(dest, src, destsize, locale->lt);
-
if (bufsize > TEXTBUFLEN)
buf = palloc(bufsize);
return result;
}
+/*
+ * strxfrm_libc
+ */
+static size_t
+strxfrm_libc(char *dest, size_t destsize, const char *src, pg_locale_t locale)
+{
+ return strxfrm_l(dest, src, destsize, locale->lt);
+}
+
char *
get_collation_actual_version_libc(const char *collcollate)
{
*
* Win32 does not have UTF-8. Convert UTF8 arguments to wide characters and
* invoke wcscoll_l().
- *
- * An input string length of -1 means that it's NUL-terminated.
*/
#ifdef WIN32
static int
-strncoll_libc_win32_utf8(const char *arg1, ssize_t len1, const char *arg2,
- ssize_t len2, pg_locale_t locale)
+strncoll_libc_win32_utf8(const char *arg1, size_t len1, const char *arg2,
+ size_t len2, pg_locale_t locale)
{
char sbuf[TEXTBUFLEN];
char *buf = sbuf;
Assert(GetDatabaseEncoding() == PG_UTF8);
- if (len1 == -1)
- len1 = strlen(arg1);
- if (len2 == -1)
- len2 = strlen(arg2);
-
/*
* In a 32-bit build, twice the input length can overflow size_t, so we
* must be careful.
return result;
}
+
+static int
+strcoll_libc_win32_utf8(const char *arg1, const char *arg2,
+ pg_locale_t locale)
+{
+ size_t len1 = strlen(arg1);
+ size_t len2 = strlen(arg2);
+
+ return strncoll_libc_win32_utf8(arg1, len1, arg2, len2, locale);
+}
#endif /* WIN32 */
/* simple subroutine for reporting errors from newlocale() */
#endif
typedef size_t (*TestFunc) (char *dst, size_t dstsize, const char *src,
- ssize_t srclen);
+ size_t srclen);
/* simple boundary iterator copied from pg_locale_builtin.c */
struct WordBoundaryState
char icu_upper[BUFSZ];
char icu_fold[BUFSZ];
UErrorCode status;
+ size_t len = strlen(str);
/* full case mapping doesn't use posix semantics */
struct WordBoundaryState wbstate = {
.prev_alnum = false,
};
- unicode_strlower(lower, BUFSZ, str, -1, true);
- unicode_strtitle(title, BUFSZ, str, -1, true, initcap_wbnext, &wbstate);
- unicode_strupper(upper, BUFSZ, str, -1, true);
- unicode_strfold(fold, BUFSZ, str, -1, true);
+ unicode_strlower(lower, BUFSZ, str, len, true);
+ unicode_strtitle(title, BUFSZ, str, len, true, initcap_wbnext, &wbstate);
+ unicode_strupper(upper, BUFSZ, str, len, true);
+ unicode_strfold(fold, BUFSZ, str, len, true);
status = U_ZERO_ERROR;
- ucasemap_utf8ToLower(casemap, icu_lower, BUFSZ, str, -1, &status);
+ ucasemap_utf8ToLower(casemap, icu_lower, BUFSZ, str, len, &status);
status = U_ZERO_ERROR;
- ucasemap_utf8ToTitle(casemap, icu_title, BUFSZ, str, -1, &status);
+ ucasemap_utf8ToTitle(casemap, icu_title, BUFSZ, str, len, &status);
status = U_ZERO_ERROR;
- ucasemap_utf8ToUpper(casemap, icu_upper, BUFSZ, str, -1, &status);
+ ucasemap_utf8ToUpper(casemap, icu_upper, BUFSZ, str, len, &status);
status = U_ZERO_ERROR;
- ucasemap_utf8FoldCase(casemap, icu_fold, BUFSZ, str, -1, &status);
+ ucasemap_utf8FoldCase(casemap, icu_fold, BUFSZ, str, len, &status);
if (strcmp(lower, icu_lower) != 0)
{
test_convert(TestFunc tfunc, const char *test_string, const char *expected)
{
size_t src1len = strlen(test_string);
- size_t src2len = -1; /* NUL-terminated */
size_t dst1len = strlen(expected);
size_t dst2len = strlen(expected) + 1; /* NUL-terminated */
char *src1 = malloc(src1len);
char *dst1 = malloc(dst1len);
- char *src2 = strdup(test_string);
char *dst2 = malloc(dst2len);
size_t needed;
memcpy(src1, test_string, src1len); /* not NUL-terminated */
- /* neither source nor destination are NUL-terminated */
+ /* destination is not NUL-terminated */
memset(dst1, 0x7F, dst1len);
needed = tfunc(dst1, dst1len, src1, src1len);
if (needed != strlen(expected))
exit(1);
}
- /* destination is NUL-terminated and source is not */
+ /* destination is NUL-terminated */
memset(dst2, 0x7F, dst2len);
needed = tfunc(dst2, dst2len, src1, src1len);
if (needed != strlen(expected))
exit(1);
}
- /* source is NUL-terminated and destination is not */
- memset(dst1, 0x7F, dst1len);
- needed = tfunc(dst1, dst1len, src2, src2len);
- if (needed != strlen(expected))
- {
- printf("case_test: convert_case test3 FAILURE: '%s' needed %zu expected %zu\n",
- test_string, needed, strlen(expected));
- printf("case_test: convert_case test3 FAILURE: needed %zu\n", needed);
- exit(1);
- }
- if (memcmp(dst1, expected, dst1len) != 0)
- {
- printf("case_test: convert_case test3 FAILURE: test: '%s' result: '%.*s' expected: '%s'\n",
- test_string, (int) dst1len, dst1, expected);
- exit(1);
- }
-
- /* both source and destination are NUL-terminated */
- memset(dst2, 0x7F, dst2len);
- needed = tfunc(dst2, dst2len, src2, src2len);
- if (needed != strlen(expected))
- {
- printf("case_test: convert_case test4 FAILURE: '%s' needed %zu expected %zu\n",
- test_string, needed, strlen(expected));
- exit(1);
- }
- if (strcmp(dst2, expected) != 0)
- {
- printf("case_test: convert_case test4 FAILURE: test: '%s' result: '%s' expected: '%s'\n",
- test_string, dst2, expected);
- exit(1);
- }
-
free(src1);
free(dst1);
- free(src2);
free(dst2);
}
static size_t
tfunc_lower(char *dst, size_t dstsize, const char *src,
- ssize_t srclen)
+ size_t srclen)
{
return unicode_strlower(dst, dstsize, src, srclen, true);
}
static size_t
tfunc_title(char *dst, size_t dstsize, const char *src,
- ssize_t srclen)
+ size_t srclen)
{
struct WordBoundaryState wbstate = {
.str = src,
- .len = (srclen < 0) ? strlen(src) : srclen,
+ .len = srclen,
.offset = 0,
.init = false,
.prev_alnum = false,
static size_t
tfunc_upper(char *dst, size_t dstsize, const char *src,
- ssize_t srclen)
+ size_t srclen)
{
return unicode_strupper(dst, dstsize, src, srclen, true);
}
static size_t
tfunc_fold(char *dst, size_t dstsize, const char *src,
- ssize_t srclen)
+ size_t srclen)
{
return unicode_strfold(dst, dstsize, src, srclen, true);
}
};
static char32_t find_case_map(char32_t ucs, const char32_t *map);
-static size_t convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+static size_t convert_case(char *dst, size_t dstsize, const char *src, size_t srclen,
CaseKind str_casekind, bool full, WordBoundaryNext wbnext,
void *wbstate);
static enum CaseMapResult casemap(char32_t u1, CaseKind casekind, bool full,
* Convert src to lowercase, and return the result length (not including
* terminating NUL).
*
- * String src must be encoded in UTF-8. If srclen < 0, src must be
- * NUL-terminated.
+ * String src must be encoded in UTF-8.
*
* Result string is stored in dst, truncating if larger than dstsize. If
* dstsize is greater than the result length, dst will be NUL-terminated;
* conditions are satisfied.
*/
size_t
-unicode_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+unicode_strlower(char *dst, size_t dstsize, const char *src, size_t srclen,
bool full)
{
return convert_case(dst, dstsize, src, srclen, CaseLower, full, NULL,
* Convert src to titlecase, and return the result length (not including
* terminating NUL).
*
- * String src must be encoded in UTF-8. If srclen < 0, src must be
- * NUL-terminated.
+ * String src must be encoded in UTF-8.
*
* Result string is stored in dst, truncating if larger than dstsize. If
* dstsize is greater than the result length, dst will be NUL-terminated;
* the string to indicate the final boundary.
*/
size_t
-unicode_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+unicode_strtitle(char *dst, size_t dstsize, const char *src, size_t srclen,
bool full, WordBoundaryNext wbnext, void *wbstate)
{
return convert_case(dst, dstsize, src, srclen, CaseTitle, full, wbnext,
* Convert src to uppercase, and return the result length (not including
* terminating NUL).
*
- * String src must be encoded in UTF-8. If srclen < 0, src must be
- * NUL-terminated.
+ * String src must be encoded in UTF-8.
*
* Result string is stored in dst, truncating if larger than dstsize. If
* dstsize is greater than the result length, dst will be NUL-terminated;
* conditions are satisfied.
*/
size_t
-unicode_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+unicode_strupper(char *dst, size_t dstsize, const char *src, size_t srclen,
bool full)
{
return convert_case(dst, dstsize, src, srclen, CaseUpper, full, NULL,
* Case fold src, and return the result length (not including terminating
* NUL).
*
- * String src must be encoded in UTF-8. If srclen < 0, src must be
- * NUL-terminated.
+ * String src must be encoded in UTF-8.
*
* Result string is stored in dst, truncating if larger than dstsize. If
* dstsize is greater than the result length, dst will be NUL-terminated;
* required buffer size before allocating.
*/
size_t
-unicode_strfold(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+unicode_strfold(char *dst, size_t dstsize, const char *src, size_t srclen,
bool full)
{
return convert_case(dst, dstsize, src, srclen, CaseFold, full, NULL,
* map a single codepoint to multiple codepoints, or depend on conditions.
*/
static size_t
-convert_case(char *dst, size_t dstsize, const char *src, ssize_t srclen,
+convert_case(char *dst, size_t dstsize, const char *src, size_t srclen,
CaseKind str_casekind, bool full, WordBoundaryNext wbnext,
void *wbstate)
{
Assert(boundary == 0); /* start of text is always a boundary */
}
- while ((srclen < 0 || srcoff < srclen) && src[srcoff] != '\0')
+ while (srcoff < srclen)
{
char32_t u1 = utf8_to_unicode((const unsigned char *) src + srcoff);
int u1len = unicode_utf8len(u1);
char32_t unicode_uppercase_simple(char32_t code);
char32_t unicode_casefold_simple(char32_t code);
size_t unicode_strlower(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, bool full);
+ size_t srclen, bool full);
size_t unicode_strtitle(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, bool full,
+ size_t srclen, bool full,
WordBoundaryNext wbnext, void *wbstate);
size_t unicode_strupper(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, bool full);
+ size_t srclen, bool full);
size_t unicode_strfold(char *dst, size_t dstsize, const char *src,
- ssize_t srclen, bool full);
+ size_t srclen, bool full);
#endif /* UNICODE_CASE_H */
struct collate_methods
{
/* required */
- int (*strncoll) (const char *arg1, ssize_t len1,
- const char *arg2, ssize_t len2,
+ int (*strncoll) (const char *arg1, size_t len1,
+ const char *arg2, size_t len2,
pg_locale_t locale);
+ int (*strcoll) (const char *arg1, const char *arg2,
+ pg_locale_t locale);
+
/* required */
size_t (*strnxfrm) (char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
+ size_t (*strxfrm) (char *dest, size_t destsize,
+ const char *src, pg_locale_t locale);
+
/* optional */
size_t (*strnxfrm_prefix) (char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
+ size_t (*strxfrm_prefix) (char *dest, size_t destsize,
+ const char *src, pg_locale_t locale);
+
/*
* If the strnxfrm method is not trusted to return the correct results,
* set strxfrm_is_safe to false. It set to false, the method will not be
{
/* case mapping: LOWER()/INITCAP()/UPPER() */
size_t (*strlower) (char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
size_t (*strtitle) (char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
size_t (*strupper) (char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
size_t (*strfold) (char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
size_t (*downcase_ident) (char *dest, size_t destsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
/* required */
extern char *get_collation_actual_version(char collprovider, const char *collcollate);
extern size_t pg_strlower(char *dst, size_t dstsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
extern size_t pg_strtitle(char *dst, size_t dstsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
extern size_t pg_strupper(char *dst, size_t dstsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
extern size_t pg_strfold(char *dst, size_t dstsize,
- const char *src, ssize_t srclen,
+ const char *src, size_t srclen,
pg_locale_t locale);
extern size_t pg_downcase_ident(char *dst, size_t dstsize,
- const char *src, ssize_t srclen);
+ const char *src, size_t srclen);
extern int pg_strcoll(const char *arg1, const char *arg2, pg_locale_t locale);
-extern int pg_strncoll(const char *arg1, ssize_t len1,
- const char *arg2, ssize_t len2, pg_locale_t locale);
+extern int pg_strncoll(const char *arg1, size_t len1,
+ const char *arg2, size_t len2, pg_locale_t locale);
extern bool pg_strxfrm_enabled(pg_locale_t locale);
extern size_t pg_strxfrm(char *dest, const char *src, size_t destsize,
pg_locale_t locale);
extern size_t pg_strnxfrm(char *dest, size_t destsize, const char *src,
- ssize_t srclen, pg_locale_t locale);
+ size_t srclen, pg_locale_t locale);
extern bool pg_strxfrm_prefix_enabled(pg_locale_t locale);
extern size_t pg_strxfrm_prefix(char *dest, const char *src, size_t destsize,
pg_locale_t locale);
extern size_t pg_strnxfrm_prefix(char *dest, size_t destsize, const char *src,
- ssize_t srclen, pg_locale_t locale);
+ size_t srclen, pg_locale_t locale);
extern bool pg_iswdigit(pg_wchar wc, pg_locale_t locale);
extern bool pg_iswalpha(pg_wchar wc, pg_locale_t locale);