Beispiel #1
0
size_t charset_decompose ( charset_t ch, char * src, size_t inlen, char * dst, size_t outlen)
{
    char *buffer;
    ucs2_t u[MAXPATHLEN];
    size_t len;
    size_t ilen;

    if ((size_t)(-1) == (len = convert_string_allocate_internal(ch, CH_UCS2, src, inlen, &buffer)) )
        return len;

    ilen=sizeof(u);

    if ( (size_t)-1 == (ilen = decompose_w((ucs2_t *)buffer, len, u, &ilen)) ) {
        free (buffer);
        return (size_t)(-1);
    }

    if ((size_t)(-1) == (len = convert_string_internal( CH_UCS2, ch, (char*)u, ilen, dst, outlen)) ) {
        free (buffer);
        return (size_t)(-1);
    }

    free(buffer);
    return (len);
}
Beispiel #2
0
size_t convert_string(charset_t from, charset_t to,
                      void const *src, size_t srclen,
                      void *dest, size_t destlen)
{
    size_t i_len, o_len;
    ucs2_t *u;
    ucs2_t buffer[MAXPATHLEN];
    ucs2_t buffer2[MAXPATHLEN];

    /* convert from_set to UCS2 */
    if ((size_t)-1 == ( o_len = convert_string_internal( from, CH_UCS2, src, srclen,
                                                           (char*) buffer, sizeof(buffer))) ) {
        LOG(log_error, logtype_default, "Conversion failed ( %s to CH_UCS2 )", charset_name(from));
        return (size_t) -1;
    }

    /* Do pre/decomposition */
    i_len = sizeof(buffer2);
    u = buffer2;
    if (charsets[to] && (charsets[to]->flags & CHARSET_DECOMPOSED) ) {
        if ( (size_t)-1 == (i_len = decompose_w(buffer, o_len, u, &i_len)) )
            return (size_t)-1;
    }
    else if (!charsets[from] || (charsets[from]->flags & CHARSET_DECOMPOSED)) {
        if ( (size_t)-1 == (i_len = precompose_w(buffer, o_len, u, &i_len)) )
            return (size_t)-1;
    }
    else {
        u = buffer;
        i_len = o_len;
    }
    /* Convert UCS2 to to_set */
    if ((size_t)(-1) == ( o_len = convert_string_internal( CH_UCS2, to, (char*) u, i_len, dest, destlen)) ) {
        LOG(log_error, logtype_default, "Conversion failed (CH_UCS2 to %s):%s", charset_name(to), strerror(errno));
        return (size_t) -1;
    }

    return o_len;
}
Beispiel #3
0
size_t charset_strlower(charset_t ch, const char *src, size_t srclen, char *dest, size_t destlen)
{
    size_t size;
    char *buffer;

    size = convert_string_allocate_internal(ch, CH_UCS2, src, srclen,
                                            (char **) &buffer);
    if (size == (size_t)-1) {
        SAFE_FREE(buffer);
        return size;
    }
    if (!strlower_w((ucs2_t *)buffer) && (dest == src)) {
        free(buffer);
        return srclen;
    }

    size = convert_string_internal(CH_UCS2, ch, buffer, size, dest, destlen);
    free(buffer);
    return size;
}
Beispiel #4
0
size_t convert_string(charset_t from, charset_t to,
		      void const *src, size_t srclen, 
		      void *dest, size_t destlen, BOOL allow_bad_conv)
{
	/*
	 * NB. We deliberately don't do a strlen here if srclen == -1.
	 * This is very expensive over millions of calls and is taken
	 * care of in the slow path in convert_string_internal. JRA.
	 */

#ifdef DEVELOPER
	SMB_ASSERT(destlen != (size_t)-1);
#endif

	if (srclen == 0)
		return 0;

	if (from != CH_UTF16LE && from != CH_UTF16BE && to != CH_UTF16LE && to != CH_UTF16BE) {
		const unsigned char *p = (const unsigned char *)src;
		unsigned char *q = (unsigned char *)dest;
		size_t slen = srclen;
		size_t dlen = destlen;
		unsigned char lastp = '\0';
		size_t retval = 0;

		/* If all characters are ascii, fast path here. */
		while (slen && dlen) {
			if ((lastp = *p) <= 0x7f) {
				*q++ = *p++;
				if (slen != (size_t)-1) {
					slen--;
				}
				dlen--;
				retval++;
				if (!lastp)
					break;
			} else {
#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
				goto general_case;
#else
				return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
#endif
			}
		}
		if (!dlen) {
			/* Even if we fast path we should note if we ran out of room. */
			if (((slen != (size_t)-1) && slen) ||
					((slen == (size_t)-1) && lastp)) {
				errno = E2BIG;
			}
		}
		return retval;
	} else if (from == CH_UTF16LE && to != CH_UTF16LE) {
		const unsigned char *p = (const unsigned char *)src;
		unsigned char *q = (unsigned char *)dest;
		size_t retval = 0;
		size_t slen = srclen;
		size_t dlen = destlen;
		unsigned char lastp = '\0';

		/* If all characters are ascii, fast path here. */
		while (((slen == (size_t)-1) || (slen >= 2)) && dlen) {
			if (((lastp = *p) <= 0x7f) && (p[1] == 0)) {
				*q++ = *p;
				if (slen != (size_t)-1) {
					slen -= 2;
				}
				p += 2;
				dlen--;
				retval++;
				if (!lastp)
					break;
			} else {
#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
				goto general_case;
#else
				return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
#endif
			}
		}
		if (!dlen) {
			/* Even if we fast path we should note if we ran out of room. */
			if (((slen != (size_t)-1) && slen) ||
					((slen == (size_t)-1) && lastp)) {
				errno = E2BIG;
			}
		}
		return retval;
	} else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) {
		const unsigned char *p = (const unsigned char *)src;
		unsigned char *q = (unsigned char *)dest;
		size_t retval = 0;
		size_t slen = srclen;
		size_t dlen = destlen;
		unsigned char lastp = '\0';

		/* If all characters are ascii, fast path here. */
		while (slen && (dlen >= 2)) {
			if ((lastp = *p) <= 0x7F) {
				*q++ = *p++;
				*q++ = '\0';
				if (slen != (size_t)-1) {
					slen--;
				}
				dlen -= 2;
				retval += 2;
				if (!lastp)
					break;
			} else {
#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
				goto general_case;
#else
				return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
#endif
			}
		}
		if (!dlen) {
			/* Even if we fast path we should note if we ran out of room. */
			if (((slen != (size_t)-1) && slen) ||
					((slen == (size_t)-1) && lastp)) {
				errno = E2BIG;
			}
		}
		return retval;
	}

#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
  general_case:
#endif
	return convert_string_internal(from, to, src, srclen, dest, destlen, allow_bad_conv);
}