/*
******************************************************************************
*
-* Copyright (C) 1998-2012, International Business Machines
+* Copyright (C) 1998-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
ucnv_safeClone(const UConverter* cnv, void *stackBuffer, int32_t *pBufferSize, UErrorCode *status)
{
UConverter *localConverter, *allocatedConverter;
+ int32_t stackBufferSize;
int32_t bufferSizeNeeded;
char *stackBufferChars = (char *)stackBuffer;
UErrorCode cbErr;
if (status == NULL || U_FAILURE(*status)){
UTRACE_EXIT_STATUS(status? *status: U_ILLEGAL_ARGUMENT_ERROR);
- return 0;
+ return NULL;
}
- if (!pBufferSize || !cnv){
+ if (cnv == NULL) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
UTRACE_EXIT_STATUS(*status);
- return 0;
+ return NULL;
}
UTRACE_DATA3(UTRACE_OPEN_CLOSE, "clone converter %s at %p into stackBuffer %p",
/* call the custom safeClone function for sizing */
bufferSizeNeeded = 0;
cnv->sharedData->impl->safeClone(cnv, NULL, &bufferSizeNeeded, status);
+ if (U_FAILURE(*status)) {
+ UTRACE_EXIT_STATUS(*status);
+ return NULL;
+ }
}
else
{
bufferSizeNeeded = sizeof(UConverter);
}
- if (*pBufferSize <= 0){ /* 'preflighting' request - set needed size into *pBufferSize */
- *pBufferSize = bufferSizeNeeded;
- UTRACE_EXIT_VALUE(bufferSizeNeeded);
- return 0;
+ if (pBufferSize == NULL) {
+ stackBufferSize = 1;
+ pBufferSize = &stackBufferSize;
+ } else {
+ stackBufferSize = *pBufferSize;
+ if (stackBufferSize <= 0){ /* 'preflighting' request - set needed size into *pBufferSize */
+ *pBufferSize = bufferSizeNeeded;
+ UTRACE_EXIT_VALUE(bufferSizeNeeded);
+ return NULL;
+ }
}
*/
if (U_ALIGNMENT_OFFSET(stackBuffer) != 0) {
int32_t offsetUp = (int32_t)U_ALIGNMENT_OFFSET_UP(stackBufferChars);
- if(*pBufferSize > offsetUp) {
- *pBufferSize -= offsetUp;
+ if(stackBufferSize > offsetUp) {
+ stackBufferSize -= offsetUp;
stackBufferChars += offsetUp;
} else {
/* prevent using the stack buffer but keep the size > 0 so that we do not just preflight */
- *pBufferSize = 1;
+ stackBufferSize = 1;
}
}
stackBuffer = (void *)stackBufferChars;
/* Now, see if we must allocate any memory */
- if (*pBufferSize < bufferSizeNeeded || stackBuffer == NULL)
+ if (stackBufferSize < bufferSizeNeeded || stackBuffer == NULL)
{
/* allocate one here...*/
localConverter = allocatedConverter = (UConverter *) uprv_malloc (bufferSizeNeeded);
UTRACE_EXIT_STATUS(*status);
return NULL;
}
-
- if (U_SUCCESS(*status)) {
- *status = U_SAFECLONE_ALLOCATED_WARNING;
- }
-
+ *status = U_SAFECLONE_ALLOCATED_WARNING;
+
/* record the fact that memory was allocated */
*pBufferSize = bufferSizeNeeded;
} else {