void CharType::printValueToFile(const TypedValue &value, FILE *file, const int padding) const { DCHECK(!value.isNull()); DCHECK_EQ(length_, static_cast<decltype(length_)>(static_cast<int>(length_))) << "Can not convert CHAR Type's maximum length " << length_ << " to int for fprintf()"; std::fprintf(file, "%*.*s", padding, static_cast<int>(length_), static_cast<const char*>(value.getOutOfLineData())); }
TypedValue CharType::coerceValue(const TypedValue &original_value, const Type &original_type) const { DCHECK(isCoercibleFrom(original_type)) << "Can't coerce value of Type " << original_type.getName() << " to Type " << getName(); if (original_value.isNull()) { return makeNullValue(); } const void *original_data = original_value.getOutOfLineData(); const std::size_t original_data_size = original_value.getDataSize(); // VARCHAR always has a null-terminator. CHAR(X) has a null-terminator when // string's length is less than X. const bool null_terminated = (original_type.getTypeID() == kVarChar) || (original_data_size < original_type.maximumByteLength()) || (std::memchr(original_data, '\0', original_data_size) != nullptr); if (original_data_size <= length_) { if (null_terminated || (original_data_size == length_)) { TypedValue value_copy(original_value); value_copy.markType(kChar); return value_copy; } else { // Need to make a new NULL-terminated copy of the string. char *null_terminated_str = static_cast<char*>(std::malloc(original_data_size + 1)); std::memcpy(null_terminated_str, original_data, original_data_size); null_terminated_str[original_data_size] = '\0'; return TypedValue::CreateWithOwnedData(kChar, null_terminated_str, original_data_size + 1); } } else { // Need to truncate. if (original_value.ownsOutOfLineData()) { char *truncated_str = static_cast<char*>(std::malloc(length_)); std::memcpy(truncated_str, original_data, length_); return TypedValue::CreateWithOwnedData(kChar, truncated_str, length_); } else { // Original is a reference, so we will just make a shorter reference. return TypedValue(kChar, original_data, length_); } } }
std::string CharType::printValueToString(const TypedValue &value) const { DCHECK(!value.isNull()); const char *cstr = static_cast<const char*>(value.getOutOfLineData()); return std::string(cstr, strnlen(cstr, length_)); }