void INTL_adjust_text_descriptor(thread_db* tdbb, dsc* desc) { /************************************** * * I N T L _ a d j u s t _ t e x t _ d e s c r i p t o r * ************************************** * * Functional description * This function receives a text descriptor with * dsc_length = numberOfCharacters * maxBytesPerChar * and change dsc_length to number of bytes used by the string. * **************************************/ if (desc->dsc_dtype == dtype_text) { SET_TDBB(tdbb); USHORT ttype = INTL_TTYPE(desc); CharSet* charSet = INTL_charset_lookup(tdbb, ttype); if (charSet->isMultiByte()) { Firebird::HalfStaticArray<UCHAR, BUFFER_SMALL> buffer; if (charSet->getFlags() & CHARSET_LEGACY_SEMANTICS) { desc->dsc_length = charSet->substring(TEXT_LEN(desc), desc->dsc_address, TEXT_LEN(desc), buffer.getBuffer(TEXT_LEN(desc) * charSet->maxBytesPerChar()), 0, TEXT_LEN(desc)); const ULONG maxLength = TEXT_LEN(desc) / charSet->maxBytesPerChar(); ULONG charLength = charSet->length(desc->dsc_length, desc->dsc_address, true); while (charLength > maxLength) { if (desc->dsc_address[desc->dsc_length - 1] == *charSet->getSpace()) { --desc->dsc_length; --charLength; } else break; } } else { desc->dsc_length = charSet->substring(TEXT_LEN(desc), desc->dsc_address, TEXT_LEN(desc), buffer.getBuffer(TEXT_LEN(desc)), 0, TEXT_LEN(desc) / charSet->maxBytesPerChar()); } } } }
static void pad_spaces(thread_db* tdbb, CHARSET_ID charset, BYTE* ptr, ULONG len) { /* byte count */ /************************************** * * p a d _ s p a c e s * ************************************** * * Functional description * Pad a buffer with the character set defined space character. * **************************************/ SET_TDBB(tdbb); fb_assert(ptr != NULL); CharSet* obj = INTL_charset_lookup(tdbb, charset); // Single-octet character sets are optimized here if (obj->getSpaceLength() == 1) { const BYTE* const end = &ptr[len]; while (ptr < end) *ptr++ = *obj->getSpace(); } else { const BYTE* const end = &ptr[len]; const UCHAR* space = obj->getSpace(); const UCHAR* const end_space = &space[obj->getSpaceLength()]; while (ptr < end) { space = obj->getSpace(); while (ptr < end && space < end_space) { *ptr++ = *space++; } // This fb_assert is checking that we didn't have a buffer-end // in the middle of a space character fb_assert(!(ptr == end) || (space == end_space)); } } }