ICU-1244 xxx_safeClone functions need to align the memory buffer on
64-bit computers. X-SVN-Rev: 5934
This commit is contained in:
parent
8710f7dca5
commit
ce583739d8
@ -37,4 +37,26 @@
|
||||
#define uprv_memset(buffer, mark, size) U_STANDARD_CPP_NAMESPACE memset(buffer, mark, size)
|
||||
#define uprv_memcmp(buffer1, buffer2, size) U_STANDARD_CPP_NAMESPACE memcmp(buffer1, buffer2,size)
|
||||
|
||||
/**
|
||||
* This should align the memory properly on any machine.
|
||||
* This is very useful for the safeClone functions.
|
||||
*/
|
||||
typedef union {
|
||||
long t1;
|
||||
double t2;
|
||||
void *t3;
|
||||
} UAlignedMemory;
|
||||
|
||||
/**
|
||||
* Get the amount of bytes that a pointer is off by from
|
||||
* the previous aligned pointer
|
||||
*/
|
||||
#define U_ALIGNMENT_OFFSET(ptr) (((long)ptr) & (sizeof(UAlignedMemory) - 1))
|
||||
|
||||
/**
|
||||
* Get the amount of bytes to add to a pointer
|
||||
* in order to get the next aligned address
|
||||
*/
|
||||
#define U_ALIGNMENT_OFFSET_UP(ptr) (sizeof(UAlignedMemory) - U_ALIGNMENT_OFFSET(ptr))
|
||||
|
||||
#endif
|
||||
|
@ -135,6 +135,7 @@ UConverter *ucnv_safeClone(const UConverter* cnv, void *stackBuffer, int32_t *pB
|
||||
{
|
||||
UConverter * localConverter;
|
||||
int32_t bufferSizeNeeded;
|
||||
char *stackBufferChars = (char *)stackBuffer;
|
||||
|
||||
if (status == NULL || U_FAILURE(*status)){
|
||||
return 0;
|
||||
@ -143,6 +144,15 @@ UConverter *ucnv_safeClone(const UConverter* cnv, void *stackBuffer, int32_t *pB
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
/* Pointers on 64-bit platforms need to be aligned
|
||||
* on a 64-bit boundry in memory.
|
||||
*/
|
||||
if (U_ALIGNMENT_OFFSET(stackBuffer) != 0) {
|
||||
int32_t offsetUp = (int32_t)U_ALIGNMENT_OFFSET_UP(stackBufferChars);
|
||||
*pBufferSize -= offsetUp;
|
||||
stackBufferChars += offsetUp;
|
||||
}
|
||||
stackBuffer = (void *)stackBufferChars;
|
||||
|
||||
if (cnv->sharedData->impl->safeClone != NULL) {
|
||||
/* call the custom safeClone function for sizing */
|
||||
@ -154,7 +164,7 @@ UConverter *ucnv_safeClone(const UConverter* cnv, void *stackBuffer, int32_t *pB
|
||||
bufferSizeNeeded = sizeof(UConverter);
|
||||
}
|
||||
|
||||
if (*pBufferSize == 0){ /* 'preflighting' request - set needed size into *pBufferSize */
|
||||
if (*pBufferSize <= 0){ /* 'preflighting' request - set needed size into *pBufferSize */
|
||||
*pBufferSize = bufferSizeNeeded;
|
||||
return 0;
|
||||
}
|
||||
|
@ -268,17 +268,22 @@ BreakIterator * DictionaryBasedBreakIterator::createBufferClone(void *stackBuff
|
||||
int32_t bufferSizeNeeded = 0;
|
||||
UBool IterIsUChar = FALSE;
|
||||
UBool IterIsString = FALSE;
|
||||
char *stackBufferChars = (char *)stackBuffer;
|
||||
|
||||
if (U_FAILURE(status)){
|
||||
return 0;
|
||||
}
|
||||
/* // Never check for NULL on the 'this' pointer.
|
||||
// It should be a fatal error when 'this' is ever NULL. [grhoten]
|
||||
if (!this){
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Pointers on 64-bit platforms need to be aligned
|
||||
* on a 64-bit boundry in memory.
|
||||
*/
|
||||
if (U_ALIGNMENT_OFFSET(stackBuffer) != 0) {
|
||||
int32_t offsetUp = (int32_t)U_ALIGNMENT_OFFSET_UP(stackBufferChars);
|
||||
BufferSize -= offsetUp;
|
||||
stackBufferChars += offsetUp;
|
||||
}
|
||||
stackBuffer = (void *)stackBufferChars;
|
||||
|
||||
if (text == NULL)
|
||||
{
|
||||
bufferSizeNeeded = (int32_t) sizeof(DictionaryBasedBreakIterator);
|
||||
@ -297,7 +302,7 @@ BreakIterator * DictionaryBasedBreakIterator::createBufferClone(void *stackBuff
|
||||
{
|
||||
// code has changed - time to make a real CharacterIterator::CreateBufferClone()
|
||||
}
|
||||
if (BufferSize == 0){ /* 'preflighting' request - set needed size into *pBufferSize */
|
||||
if (BufferSize <= 0){ /* 'preflighting' request - set needed size into *pBufferSize */
|
||||
BufferSize = bufferSizeNeeded;
|
||||
return 0;
|
||||
}
|
||||
|
@ -584,17 +584,22 @@ BreakIterator * RuleBasedBreakIterator::createBufferClone(void *stackBuffer,
|
||||
int32_t bufferSizeNeeded = 0;
|
||||
UBool IterIsUChar = FALSE;
|
||||
UBool IterIsString = FALSE;
|
||||
char *stackBufferChars = (char *)stackBuffer;
|
||||
|
||||
if (U_FAILURE(status)){
|
||||
return 0;
|
||||
}
|
||||
/* // Never check for NULL on the 'this' pointer.
|
||||
// It should be a fatal error when 'this' is ever NULL. [grhoten]
|
||||
if (!this){
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Pointers on 64-bit platforms need to be aligned
|
||||
* on a 64-bit boundry in memory.
|
||||
*/
|
||||
if (U_ALIGNMENT_OFFSET(stackBuffer) != 0) {
|
||||
int32_t offsetUp = (int32_t)U_ALIGNMENT_OFFSET_UP(stackBufferChars);
|
||||
BufferSize -= offsetUp;
|
||||
stackBufferChars += offsetUp;
|
||||
}
|
||||
stackBuffer = (void *)stackBufferChars;
|
||||
|
||||
if (text == NULL)
|
||||
{
|
||||
bufferSizeNeeded = (int32_t) sizeof(RuleBasedBreakIterator);
|
||||
@ -613,7 +618,7 @@ BreakIterator * RuleBasedBreakIterator::createBufferClone(void *stackBuffer,
|
||||
{
|
||||
// code has changed - time to make a real CharacterIterator::CreateBufferClone()
|
||||
}
|
||||
if (BufferSize == 0){ /* 'preflighting' request - set needed size into *pBufferSize */
|
||||
if (BufferSize <= 0){ /* 'preflighting' request - set needed size into *pBufferSize */
|
||||
BufferSize = bufferSizeNeeded;
|
||||
return 0;
|
||||
}
|
||||
|
@ -4283,6 +4283,7 @@ ucol_safeClone(const UCollator *coll, void *stackBuffer, int32_t * pBufferSize,
|
||||
{
|
||||
UCollator * localCollator;
|
||||
int32_t bufferSizeNeeded = (int32_t)sizeof(UCollator);
|
||||
char *stackBufferChars = (char *)stackBuffer;
|
||||
|
||||
if (status == NULL || U_FAILURE(*status)){
|
||||
return 0;
|
||||
@ -4291,7 +4292,17 @@ ucol_safeClone(const UCollator *coll, void *stackBuffer, int32_t * pBufferSize,
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
if (*pBufferSize == 0){ /* 'preflighting' request - set needed size into *pBufferSize */
|
||||
/* Pointers on 64-bit platforms need to be aligned
|
||||
* on a 64-bit boundry in memory.
|
||||
*/
|
||||
if (U_ALIGNMENT_OFFSET(stackBuffer) != 0) {
|
||||
int32_t offsetUp = (int32_t)U_ALIGNMENT_OFFSET_UP(stackBufferChars);
|
||||
*pBufferSize -= offsetUp;
|
||||
stackBufferChars += offsetUp;
|
||||
}
|
||||
stackBuffer = (void *)stackBufferChars;
|
||||
|
||||
if (*pBufferSize <= 0){ /* 'preflighting' request - set needed size into *pBufferSize */
|
||||
*pBufferSize = bufferSizeNeeded;
|
||||
return 0;
|
||||
}
|
||||
|
@ -470,12 +470,13 @@ void TestSafeClone() {
|
||||
UCollator * someClonedCollators [CLONETEST_COLLATOR_COUNT];
|
||||
UCollator * col;
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
int8_t testSize = 6; /* Leave this here to test buffer alingment in memory*/
|
||||
uint8_t buffer [CLONETEST_COLLATOR_COUNT] [U_COL_SAFECLONE_BUFFERSIZE];
|
||||
int32_t bufferSize = U_COL_SAFECLONE_BUFFERSIZE;
|
||||
int index;
|
||||
|
||||
test1=(UChar*)malloc(sizeof(UChar) * 6);
|
||||
test2=(UChar*)malloc(sizeof(UChar) * 6);
|
||||
test1=(UChar*)malloc(sizeof(UChar) * testSize);
|
||||
test2=(UChar*)malloc(sizeof(UChar) * testSize);
|
||||
u_uastrcpy(test1, "abCda");
|
||||
u_uastrcpy(test2, "abcda");
|
||||
|
||||
|
@ -38,7 +38,6 @@ static void TestBreakIteratorCAPI()
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UBreakIterator *word, *sentence, *line, *character, *b, *bogus;
|
||||
UChar text[50];
|
||||
UTextOffset start,pos,end,to;
|
||||
int32_t i;
|
||||
int32_t count = 0;
|
||||
@ -46,11 +45,11 @@ static void TestBreakIteratorCAPI()
|
||||
UBreakIterator * someIterators [CLONETEST_ITERATOR_COUNT];
|
||||
UBreakIterator * someClonedIterators [CLONETEST_ITERATOR_COUNT];
|
||||
UBreakIterator * brk;
|
||||
UChar text[51]; /* Keep this odd to test for 64-bit memory alignment */
|
||||
uint8_t buffer [CLONETEST_ITERATOR_COUNT] [U_BRK_SAFECLONE_BUFFERSIZE];
|
||||
int32_t bufferSize = U_BRK_SAFECLONE_BUFFERSIZE;
|
||||
|
||||
u_uastrcpy(text, "He's from Africa. ""Mr. Livingston, I presume?"" Yeah");
|
||||
status = U_ZERO_ERROR;
|
||||
|
||||
|
||||
/*test ubrk_open()*/
|
||||
|
@ -1086,7 +1086,14 @@ static void TestConvertSafeClone()
|
||||
{
|
||||
#define CLONETEST_CONVERTER_COUNT 8
|
||||
|
||||
char charBuffer [20];
|
||||
char charBuffer [21]; /* Leave at an odd number for alignment testing */
|
||||
uint8_t buffer [CLONETEST_CONVERTER_COUNT] [U_CNV_SAFECLONE_BUFFERSIZE];
|
||||
int32_t bufferSize = U_CNV_SAFECLONE_BUFFERSIZE;
|
||||
UConverter * someConverters [CLONETEST_CONVERTER_COUNT];
|
||||
UConverter * someClonedConverters [CLONETEST_CONVERTER_COUNT];
|
||||
UConverter * cnv;
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
|
||||
char *pCharBuffer;
|
||||
const char *pConstCharBuffer;
|
||||
const char *charBufferLimit = charBuffer + sizeof(charBuffer)/sizeof(*charBuffer);
|
||||
@ -1101,13 +1108,6 @@ static void TestConvertSafeClone()
|
||||
const UChar *uniBufferLimit = uniBuffer + sizeof(uniBuffer)/sizeof(*uniBuffer);
|
||||
int index;
|
||||
|
||||
UConverter * someConverters [CLONETEST_CONVERTER_COUNT];
|
||||
UConverter * someClonedConverters [CLONETEST_CONVERTER_COUNT];
|
||||
UConverter * cnv;
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
uint8_t buffer [CLONETEST_CONVERTER_COUNT] [U_CNV_SAFECLONE_BUFFERSIZE];
|
||||
int32_t bufferSize = U_CNV_SAFECLONE_BUFFERSIZE;
|
||||
|
||||
/* one 'regular' & all the 'private stateful' converters */
|
||||
someConverters[0] = ucnv_open("ibm-1047", &err);
|
||||
someConverters[1] = ucnv_open("ISO_2022", &err);
|
||||
|
Loading…
Reference in New Issue
Block a user