/*
*-----------------------------------------------------------------------------
*
* Unicode_AllocWithLength --
*
* Allocates a new Unicode string given a buffer with both length
* in bytes and string encoding specified.
*
* If lengthInBytes is -1, then buffer must be NUL-terminated.
* Otherwise, buffer must be of the specified length, but does
* not need to be NUL-terminated.
*
* If buffer is NULL, then NULL is returned.
* In this case, lengthInBytes must be 0 or -1, consistent with
* an empty string.
*
* Note that regardless of the encoding of the buffer passed to this
* function, the returned string can hold any Unicode characters.
*
* If the buffer contains an invalid sequence of the specified
* encoding or memory could not be allocated, logs the buffer,
* and panics.
*
* Results:
* An allocated Unicode string containing the decoded characters
* in buffer, or NULL if input is NULL.
* Caller must pass the string to free to free.
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
char *
Unicode_AllocWithLength(const void *buffer, // IN:
ssize_t lengthInBytes, // IN:
StringEncoding encoding) // IN:
{
char *result;
ASSERT(lengthInBytes >= 0 || lengthInBytes == -1);
if (buffer == NULL) {
ASSERT(lengthInBytes <= 0);
return NULL;
}
encoding = Unicode_ResolveEncoding(encoding);
if (lengthInBytes == -1) {
lengthInBytes = Unicode_LengthInBytes(buffer, encoding);
}
result = UnicodeAllocInternal(buffer, lengthInBytes, encoding, FALSE);
if (result == NULL) {
char *escapedBuffer = Unicode_EscapeBuffer(buffer, lengthInBytes,
encoding);
/*
* Log and panic on failure.
*/
Log("%s: Couldn't convert invalid buffer [%s] from %s to Unicode.\n",
__FUNCTION__,
escapedBuffer ? escapedBuffer : "(couldn't escape bytes)",
Unicode_EncodingEnumToName(encoding));
free(escapedBuffer);
PANIC();
}
return result;
}