ICU-1244 xxx_safeClone functions need to align the memory buffer on

64-bit computers.

X-SVN-Rev: 5934
This commit is contained in:
George Rhoten 2001-09-26 21:09:18 +00:00
parent 8710f7dca5
commit ce583739d8
8 changed files with 81 additions and 28 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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");

View File

@ -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()*/

View File

@ -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);