Trying to clean up some code and i wanted to know if the following is a safe way to cast uint16_t to a wchar_t.
#if ! defined(MARKUP_SIZEOFWCHAR)
#if __SIZEOF_WCHAR_T__ == 4 || __WCHAR_MAX__ > 0x10000
#define MARKUP_SIZEOFWCHAR 4
#else
#define MARKUP_SIZEOFWCHAR 2
#endif
void FileReader::parseBuffer(char * buffer, int length)
{
//start by looking for a vrsn
//Header seek around for a vrns followed by 32 bit size descriptor
//read 32 bits at a time
int cursor = 0;
char vrsn[5] = "vrsn";
cursor = this->searchForMarker(cursor, length, vrsn, buffer);
int32_t size = this->getObjectSizeForMarker(cursor, length, buffer);
cursor = cursor + 7; //advance cursor past marker and size
wchar_t *version = this->getObjectForSizeAndCursor(size, cursor, buffer);
wcout << version;
delete[] version; //this pointer is dest from getObjectForSizeAndCursor
}
–
wchar_t* FileReader::getObjectForSizeAndCursor(int32_t size, int cursor, char *buffer) {
int wlen = size/2;
uint32_t *dest = new uint32_t[wlen+1];
unsigned char *ptr = (unsigned char *)(buffer + cursor);
for(int i=0; i<wlen; i++) {
#if MARKUP_SIZEOFWCHAR == 4 // sizeof(wchar_t) == 4
char padding[2] = {'\0','\0'};
dest[i] = (padding[0] << 24) + (padding[1] << 16) + (ptr[0] << 8) + ptr[1];
#else // sizeof(wchar_t) == 2
dest[i] = (ptr[0] << 8) + ptr[1];
#endif
ptr += 2;
cout << ptr;
}
return (wchar_t *)dest;
}
do i have any scoping issues with the way i am using the padding? will i leak padding when i delete dest[] in the calling function?
The distinction
is completely unnecessary.
padding[i]is 0, so shifting that left keeps it 0, and adding it has no effect.The compiler may or may not optimise the allocation of the two-byte array
paddingin each loop iteration away, but since it is an automatic array, it cannot leak in any way.Since the types used in the loop are unsigned, simply using
is perfectly safe. (The endianness must of course be correct.)
For
you should let the type of
destdepend on the size ofwchar_t, it should beuint16_t*ifsizeof(wchar_t) == 2(andCHAR_BIT == 8).