in sql-odbc/src/sqlodbc/convert.c [659:848]
static int setup_getdataclass(SQLLEN *const length_return,
const char **const ptr_return,
int *needbuflen_return, GetDataClass *const esdc,
const char *neut_str, const OID field_type,
const SQLSMALLINT fCType, const SQLLEN cbValueMax,
const ConnectionClass *const conn) {
SQLLEN len = (-2);
const char *ptr = NULL;
int needbuflen = 0;
int result = COPY_OK;
BOOL lf_conv = 0;
int bytea_process_kind = 0;
BOOL already_processed = FALSE;
BOOL changed = FALSE;
int len_for_wcs_term = 0;
#ifdef UNICODE_SUPPORT
char *allocbuf = NULL;
int unicode_count = -1;
BOOL localize_needed = FALSE;
BOOL hybrid = FALSE;
#endif /* UNICODE_SUPPORT */
if (OPENSEARCH_TYPE_BYTEA == field_type) {
if (SQL_C_BINARY == fCType)
bytea_process_kind = BYTEA_PROCESS_BINARY;
else if (0 == strnicmp(neut_str, "\\x", 2)) /* hex format */
neut_str += 2;
else
bytea_process_kind = BYTEA_PROCESS_ESCAPE;
}
#ifdef UNICODE_SUPPORT
if (0 == bytea_process_kind) {
if (get_convtype()
> 0) /* coversion between the current locale is available */
{
BOOL wcs_debug = 0;
BOOL same_encoding =
(conn->ccsc == opensearch_CS_code(conn->locale_encoding));
BOOL is_utf8 = (UTF8 == conn->ccsc);
switch (field_type) {
case OPENSEARCH_TYPE_UNKNOWN:
case OPENSEARCH_TYPE_BPCHAR:
case OPENSEARCH_TYPE_VARCHAR:
case OPENSEARCH_TYPE_TEXT:
case OPENSEARCH_TYPE_BPCHARARRAY:
case OPENSEARCH_TYPE_VARCHARARRAY:
case OPENSEARCH_TYPE_TEXTARRAY:
if (SQL_C_CHAR == fCType || SQL_C_BINARY == fCType)
localize_needed = (!same_encoding || wcs_debug);
if (SQL_C_WCHAR == fCType)
hybrid = (!is_utf8 || (same_encoding && wcs_debug));
}
MYLOG(OPENSEARCH_DEBUG,
"localize=%d hybrid=%d is_utf8=%d same_encoding=%d "
"wcs_debug=%d\n",
localize_needed, hybrid, is_utf8, same_encoding, wcs_debug);
}
}
if (fCType == SQL_C_WCHAR) {
if (BYTEA_PROCESS_ESCAPE == bytea_process_kind)
unicode_count = (int)convert_from_opensearchbinary(neut_str, NULL, 0) * 2;
else if (hybrid) {
MYLOG(OPENSEARCH_DEBUG, "hybrid estimate\n");
if ((unicode_count =
(int)bindcol_hybrid_estimate(neut_str, lf_conv, &allocbuf))
< 0) {
result = COPY_INVALID_STRING_CONVERSION;
goto cleanup;
}
} else /* normally */
{
unicode_count = (int)utf8_to_ucs2_lf(neut_str, SQL_NTS, lf_conv,
NULL, 0, FALSE);
}
len = WCLEN * unicode_count;
already_processed = changed = TRUE;
} else if (localize_needed) {
if ((len = bindcol_localize_estimate(neut_str, lf_conv, &allocbuf))
< 0) {
result = COPY_INVALID_STRING_CONVERSION;
goto cleanup;
}
already_processed = changed = TRUE;
}
#endif /* UNICODE_SUPPORT */
if (already_processed) /* skip */
;
else if (0 != bytea_process_kind) {
len = convert_from_opensearchbinary(neut_str, NULL, 0);
if (BYTEA_PROCESS_BINARY != bytea_process_kind)
len *= 2;
changed = TRUE;
} else
/* convert linefeeds to carriage-return/linefeed */
len = convert_linefeeds(neut_str, NULL, 0, lf_conv, &changed);
/* just returns length info */
if (cbValueMax == 0) {
result = COPY_RESULT_TRUNCATED;
goto cleanup;
}
if (!esdc->ttlbuf)
esdc->ttlbuflen = 0;
needbuflen = (int)len + get_terminator_len(fCType);
if (SQL_C_BINARY == fCType) {
/*
* Though Binary doesn't have NULL terminator,
* bindcol_localize_exec() needs output buffer
* for NULL terminator.
*/
len_for_wcs_term = 1;
}
if (changed || needbuflen > cbValueMax) {
if (needbuflen > (SQLLEN)esdc->ttlbuflen) {
esdc->ttlbuf = realloc(esdc->ttlbuf, needbuflen + len_for_wcs_term);
esdc->ttlbuflen = needbuflen;
}
already_processed = FALSE;
#ifdef UNICODE_SUPPORT
if (fCType == SQL_C_WCHAR) {
if (BYTEA_PROCESS_ESCAPE == bytea_process_kind) {
len = convert_from_opensearchbinary(neut_str, esdc->ttlbuf,
esdc->ttlbuflen);
len = es_bin2whex(esdc->ttlbuf, (SQLWCHAR *)esdc->ttlbuf, len);
} else {
if (!hybrid) /* normally */
utf8_to_ucs2_lf(neut_str, SQL_NTS, lf_conv,
(SQLWCHAR *)esdc->ttlbuf, unicode_count,
FALSE);
else /* hybrid */
{
MYLOG(OPENSEARCH_DEBUG, "hybrid convert\n");
if (bindcol_hybrid_exec((SQLWCHAR *)esdc->ttlbuf, neut_str,
unicode_count + 1, lf_conv,
&allocbuf)
< 0) {
result = COPY_INVALID_STRING_CONVERSION;
goto cleanup;
}
}
}
already_processed = TRUE;
} else if (localize_needed) {
if (bindcol_localize_exec(esdc->ttlbuf, len + 1, lf_conv, &allocbuf)
< 0) {
result = COPY_INVALID_STRING_CONVERSION;
goto cleanup;
}
already_processed = TRUE;
}
#endif /* UNICODE_SUPPORT */
if (already_processed)
;
else if (0 != bytea_process_kind) {
len = convert_from_opensearchbinary(neut_str, esdc->ttlbuf,
esdc->ttlbuflen);
if (BYTEA_PROCESS_ESCAPE == bytea_process_kind)
len = opensearch_bin2hex(esdc->ttlbuf, esdc->ttlbuf, len);
} else
convert_linefeeds(neut_str, esdc->ttlbuf, esdc->ttlbuflen, lf_conv,
&changed);
ptr = esdc->ttlbuf;
esdc->ttlbufused = len;
} else {
if (esdc->ttlbuf) {
free(esdc->ttlbuf);
esdc->ttlbuf = NULL;
}
ptr = neut_str;
}
cleanup:
#ifdef UNICODE_SUPPORT
if (allocbuf)
free(allocbuf);
#endif /* UNICODE_SUPPORT */
*length_return = len;
*ptr_return = ptr;
*needbuflen_return = needbuflen;
return result;
}