Commit e1716475 authored by Hiroshi Inoue's avatar Hiroshi Inoue

Add files for Unicode support.

parent 8f0a9e85
......@@ -266,6 +266,7 @@ struct ConnectionClass_
Int2 pg_version_major;
Int2 pg_version_minor;
char ms_jet;
char unicode;
#ifdef MULTIBYTE
char *client_encoding;
char *server_encoding;
......
/*-------
* Module: odbcapi25w.c
*
* Description: This module contains UNICODE routines
*
* Classes: n/a
*
* API functions: SQLColAttributesW, SQLErrorW, SQLGetConnectOptionW,
SQLSetConnectOptionW
*-------
*/
#include "psqlodbc.h"
#include <stdio.h>
#include <string.h>
#include "pgapifunc.h"
#include "connection.h"
#include "statement.h"
RETCODE SQL_API SQLErrorW(HENV EnvironmentHandle,
HDBC ConnectionHandle, HSTMT StatementHandle,
SQLWCHAR *Sqlstate, SQLINTEGER *NativeError,
SQLWCHAR *MessageText, SQLSMALLINT BufferLength,
SQLSMALLINT *TextLength)
{
RETCODE ret;
SWORD tlen;
char *qst = NULL, *mtxt = NULL;
mylog("[SQLErrorW]");
if (Sqlstate)
qst = malloc(8);
if (MessageText)
mtxt = malloc(BufferLength);
ret = PGAPI_Error(EnvironmentHandle, ConnectionHandle, StatementHandle,
qst, NativeError, mtxt, BufferLength, &tlen);
if (qst)
utf8_to_ucs2(qst, strlen(qst), Sqlstate, 5);
if (TextLength)
*TextLength = utf8_to_ucs2(mtxt, tlen, MessageText, BufferLength);
free(qst);
free(mtxt);
return ret;
}
RETCODE SQL_API SQLGetConnectOptionW(HDBC ConnectionHandle,
SQLUSMALLINT Option, PTR Value)
{
mylog("[SQLGetConnectOptionW]");
((ConnectionClass *) ConnectionHandle)->unicode = 1;
return PGAPI_GetConnectOption(ConnectionHandle, Option, Value);
}
RETCODE SQL_API SQLSetConnectOptionW(HDBC ConnectionHandle,
SQLUSMALLINT Option, SQLUINTEGER Value)
{
mylog("[SQLSetConnectionOptionW]");
((ConnectionClass *) ConnectionHandle)->unicode = 1;
return PGAPI_SetConnectOption(ConnectionHandle, Option, Value);
}
RETCODE SQL_API SQLColAttributesW(
HSTMT hstmt,
SQLUSMALLINT icol,
SQLUSMALLINT fDescType,
PTR rgbDesc,
SQLSMALLINT cbDescMax,
SQLSMALLINT *pcbDesc,
SQLINTEGER *pfDesc)
{
mylog("[SQLColAttributesW]");
return PGAPI_ColAttributes(hstmt, icol, fDescType, rgbDesc,
cbDescMax, pcbDesc, pfDesc);
}
/*-------
* Module: odbcapi30w.c
*
* Description: This module contains UNICODE routines
*
* Classes: n/a
*
* API functions: SQLColAttributeW, SQLGetStmtW, SQLSetStmtW,
SQLSetConnectAttrW, SQLGetConnectAttrW,
SQLGetDescFieldW, SQLGetDescRecW, SQLGetDiagFieldW,
SQLGetDiagRecW,
*-------
*/
#include "psqlodbc.h"
#include <stdio.h>
#include <string.h>
#include "pgapifunc.h"
#include "connection.h"
#include "statement.h"
RETCODE SQL_API SQLGetStmtAttrW(SQLHSTMT hstmt,
SQLINTEGER fAttribute,
PTR rgbValue,
SQLINTEGER cbValueMax,
SQLINTEGER *pcbValue)
{
RETCODE ret;
mylog("[SQLGetStmtAttrW]");
ret = PGAPI_GetStmtAttr(hstmt, fAttribute, rgbValue,
cbValueMax, pcbValue);
return ret;
}
RETCODE SQL_API SQLSetStmtAttrW(SQLHSTMT hstmt,
SQLINTEGER fAttribute,
PTR rgbValue,
SQLINTEGER cbValueMax)
{
RETCODE ret;
mylog("[SQLSetStmtAttrW]");
ret = PGAPI_SetStmtAttr(hstmt, fAttribute, rgbValue,
cbValueMax);
return ret;
}
RETCODE SQL_API SQLGetConnectAttrW(HDBC hdbc,
SQLINTEGER fAttribute,
PTR rgbValue,
SQLINTEGER cbValueMax,
SQLINTEGER *pcbValue)
{
RETCODE ret;
mylog("[SQLGetConnectAttrW]");
ret = PGAPI_GetConnectAttr(hdbc, fAttribute, rgbValue,
cbValueMax, pcbValue);
return ret;
}
RETCODE SQL_API SQLSetConnectAttrW(HDBC hdbc,
SQLINTEGER fAttribute,
PTR rgbValue,
SQLINTEGER cbValue)
{
RETCODE ret;
mylog("[SQLSetConnectAttrW]");
ret = PGAPI_SetConnectAttr(hdbc, fAttribute, rgbValue,
cbValue);
return ret;
}
RETCODE SQL_API SQLGetDiagRecW(SWORD fHandleType,
SQLHANDLE handle,
SQLSMALLINT iRecord,
SQLWCHAR *szSqlState,
SQLINTEGER *pfNativeError,
SQLWCHAR *szErrorMsg,
SQLSMALLINT cbErrorMsgMax,
SQLSMALLINT *pcbErrorMsg)
{
RETCODE ret;
SWORD tlen;
char *qst = NULL, *mtxt = NULL;
mylog("[SQLGetDiagRecW]");
if (szSqlState)
qst = malloc(8);
if (szErrorMsg)
mtxt = malloc(cbErrorMsgMax);
ret = PGAPI_GetDiagRec(fHandleType, handle, iRecord, qst,
pfNativeError, mtxt, cbErrorMsgMax, &tlen);
if (qst)
utf8_to_ucs2(qst, strlen(qst), szSqlState, 5);
if (pcbErrorMsg)
*pcbErrorMsg = utf8_to_ucs2(mtxt, tlen, szErrorMsg, cbErrorMsgMax);
free(qst);
free(mtxt);
return ret;
}
RETCODE SQL_API SQLColAttributeW(
HSTMT hstmt,
SQLUSMALLINT icol,
SQLUSMALLINT fDescType,
PTR rgbDesc,
SQLSMALLINT cbDescMax,
SQLSMALLINT *pcbDesc,
SQLINTEGER *pfDesc)
{
RETCODE ret;
mylog("[SQLColAttributeW]");
ret = PGAPI_ColAttributes(hstmt, icol, fDescType, rgbDesc,
cbDescMax, pcbDesc, pfDesc);
return ret;
}
/*-------
* Module: odbcapiw.c
*
* Description: This module contains UNICODE routines
*
* Classes: n/a
*
* API functions: SQLColumnPrivilegesW, SQLColumnsW,
SQLConnectW, SQLDataSourcesW, SQLDescribeColW,
SQLDriverConnectW, SQLExecDirectW,
SQLForeignKeysW,
SQLGetCursorNameW, SQLGetInfoW, SQLNativeSqlW,
SQLPrepareW, SQLPrimaryKeysW, SQLProcedureColumnsW,
SQLProceduresW, SQLSetCursorNameW,
SQLSpecialColumnsW, SQLStatisticsW, SQLTablesW,
SQLTablePrivilegesW
*-------
*/
#include "psqlodbc.h"
#include <stdio.h>
#include <string.h>
#include "pgapifunc.h"
#include "connection.h"
#include "statement.h"
RETCODE SQL_API SQLColumnsW(HSTMT StatementHandle,
SQLWCHAR *CatalogName, SQLSMALLINT NameLength1,
SQLWCHAR *SchemaName, SQLSMALLINT NameLength2,
SQLWCHAR *TableName, SQLSMALLINT NameLength3,
SQLWCHAR *ColumnName, SQLSMALLINT NameLength4)
{
RETCODE ret;
char *ctName, *scName, *tbName, *clName;
UInt4 nmlen1, nmlen2, nmlen3, nmlen4;
mylog("[SQLColumnsW]");
ctName = ucs2_to_utf8(CatalogName, NameLength1, &nmlen1);
scName = ucs2_to_utf8(SchemaName, NameLength2, &nmlen2);
tbName = ucs2_to_utf8(TableName, NameLength3, &nmlen3);
clName = ucs2_to_utf8(ColumnName, NameLength4, &nmlen4);
ret = PGAPI_Columns(StatementHandle, ctName, (SWORD) nmlen1,
scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3,
clName, (SWORD) nmlen4, 0);
if (ctName)
free(ctName);
if (scName);
free(scName);
if (tbName)
free(tbName);
if (clName);
free(clName);
return ret;
}
RETCODE SQL_API SQLConnectW(HDBC ConnectionHandle,
SQLWCHAR *ServerName, SQLSMALLINT NameLength1,
SQLWCHAR *UserName, SQLSMALLINT NameLength2,
SQLWCHAR *Authentication, SQLSMALLINT NameLength3)
{
char *svName, *usName, *auth;
UInt4 nmlen1, nmlen2, nmlen3;
RETCODE ret;
mylog("[SQLConnectW]");
((ConnectionClass *) ConnectionHandle)->unicode = 1;
svName = ucs2_to_utf8(ServerName, NameLength1, &nmlen1);
usName = ucs2_to_utf8(UserName, NameLength2, &nmlen2);
auth = ucs2_to_utf8(Authentication, NameLength3, &nmlen3);
ret = PGAPI_Connect(ConnectionHandle, svName, (SWORD) nmlen1,
usName, (SWORD) nmlen2, auth, (SWORD) nmlen3);
if (svName);
free(svName);
if (usName);
free(usName);
if (auth);
free(auth);
return ret;
}
RETCODE SQL_API SQLDriverConnectW(HDBC hdbc,
HWND hwnd,
SQLWCHAR *szConnStrIn,
SWORD cbConnStrIn,
SQLWCHAR *szConnStrOut,
SWORD cbConnStrOutMax,
SWORD FAR *pcbConnStrOut,
UWORD fDriverCompletion)
{
char *szIn, *szOut;
UInt4 inlen, obuflen;
SWORD olen;
RETCODE ret;
mylog("[SQLDriverConnectW]");
((ConnectionClass *) hdbc)->unicode = 1;
szIn = ucs2_to_utf8(szConnStrIn, cbConnStrIn, &inlen);
obuflen = cbConnStrOutMax + 1;
szOut = malloc(obuflen);
ret = PGAPI_DriverConnect(hdbc, hwnd, szIn, (SWORD) inlen,
szOut, cbConnStrOutMax, &olen, fDriverCompletion);
if (ret != SQL_ERROR)
*pcbConnStrOut = utf8_to_ucs2(szOut, olen, szConnStrOut, cbConnStrOutMax);
free(szOut);
if (szIn);
free(szIn);
return ret;
}
RETCODE SQL_API SQLBrowseConnectW(
HDBC hdbc,
SQLWCHAR *szConnStrIn,
SQLSMALLINT cbConnStrIn,
SQLWCHAR *szConnStrOut,
SQLSMALLINT cbConnStrOutMax,
SQLSMALLINT *pcbConnStrOut)
{
char *szIn, *szOut;
UInt4 inlen, obuflen;
SWORD olen;
RETCODE ret;
mylog("[SQLBrowseConnectW]");
((ConnectionClass *) hdbc)->unicode = 1;
szIn = ucs2_to_utf8(szConnStrIn, cbConnStrIn, &inlen);
obuflen = cbConnStrOutMax + 1;
szOut = malloc(obuflen);
ret = PGAPI_BrowseConnect(hdbc, szIn, (SWORD) inlen,
szOut, cbConnStrOutMax, &olen);
if (ret != SQL_ERROR)
*pcbConnStrOut = utf8_to_ucs2(szOut, olen, szConnStrOut, cbConnStrOutMax);
free(szOut);
if (szIn);
free(szIn);
return ret;
}
RETCODE SQL_API SQLDataSourcesW(HENV EnvironmentHandle,
SQLUSMALLINT Direction, SQLWCHAR *ServerName,
SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1,
SQLWCHAR *Description, SQLSMALLINT BufferLength2,
SQLSMALLINT *NameLength2)
{
mylog("[SQLDataSourcesW]");
/*
return PGAPI_DataSources(EnvironmentHandle, Direction, ServerName,
BufferLength1, NameLength1, Description, BufferLength2,
NameLength2);
*/
return SQL_ERROR;
}
RETCODE SQL_API SQLDescribeColW(HSTMT StatementHandle,
SQLUSMALLINT ColumnNumber, SQLWCHAR *ColumnName,
SQLSMALLINT BufferLength, SQLSMALLINT *NameLength,
SQLSMALLINT *DataType, SQLUINTEGER *ColumnSize,
SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable)
{
RETCODE ret;
SWORD nmlen;
char *clName;
mylog("[SQLDescribeColW]");
clName = malloc(BufferLength);
ret = PGAPI_DescribeCol(StatementHandle, ColumnNumber,
clName, BufferLength, &nmlen,
DataType, ColumnSize, DecimalDigits, Nullable);
*NameLength = utf8_to_ucs2(clName, nmlen, ColumnName, BufferLength);
free(clName);
return ret;
}
RETCODE SQL_API SQLExecDirectW(HSTMT StatementHandle,
SQLWCHAR *StatementText, SQLINTEGER TextLength)
{
RETCODE ret;
char *stxt;
UInt4 slen;
mylog("[SQLExecDirectW]");
stxt = ucs2_to_utf8(StatementText, TextLength, &slen);
ret = PGAPI_ExecDirect(StatementHandle, stxt, slen);
if (stxt);
free(stxt);
return ret;
}
RETCODE SQL_API SQLGetCursorNameW(HSTMT StatementHandle,
SQLWCHAR *CursorName, SQLSMALLINT BufferLength,
SQLSMALLINT *NameLength)
{
RETCODE ret;
char *crName;
SWORD clen;
mylog("[SQLGetCursorNameW]");
crName = malloc(BufferLength);
ret = PGAPI_GetCursorName(StatementHandle, crName, BufferLength,
&clen);
*NameLength = utf8_to_ucs2(crName, (Int4) clen, CursorName, BufferLength);
free(crName);
return ret;
}
RETCODE SQL_API SQLGetInfoW(HDBC ConnectionHandle,
SQLUSMALLINT InfoType, PTR InfoValue,
SQLSMALLINT BufferLength, SQLSMALLINT *StringLength)
{
RETCODE ret;
((ConnectionClass *) ConnectionHandle)->unicode = 1;
#if (ODBCVER >= 0x0300)
mylog("[SQLGetInfoW(30)]");
if ((ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue,
BufferLength, StringLength)) == SQL_ERROR)
{
if (((ConnectionClass *) ConnectionHandle)->driver_version >= 0x0300)
return PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue,
BufferLength, StringLength);
}
return ret;
#else
mylog("[SQLGetInfoW]");
return PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue,
BufferLength, StringLength);
#endif
}
RETCODE SQL_API SQLPrepareW(HSTMT StatementHandle,
SQLWCHAR *StatementText, SQLINTEGER TextLength)
{
RETCODE ret;
char *stxt;
UInt4 slen;
mylog("[SQLPrepareW]");
stxt = ucs2_to_utf8(StatementText, TextLength, &slen);
ret = PGAPI_Prepare(StatementHandle, stxt, slen);
if (stxt);
free(stxt);
return ret;
}
RETCODE SQL_API SQLSetCursorNameW(HSTMT StatementHandle,
SQLWCHAR *CursorName, SQLSMALLINT NameLength)
{
RETCODE ret;
char *crName;
UInt4 nlen;
mylog("[SQLSetCursorNameW]");
crName = ucs2_to_utf8(CursorName, NameLength, &nlen);
ret = PGAPI_SetCursorName(StatementHandle, crName, (SWORD) nlen);
if (crName);
free(crName);
return ret;
}
RETCODE SQL_API SQLSpecialColumnsW(HSTMT StatementHandle,
SQLUSMALLINT IdentifierType, SQLWCHAR *CatalogName,
SQLSMALLINT NameLength1, SQLWCHAR *SchemaName,
SQLSMALLINT NameLength2, SQLWCHAR *TableName,
SQLSMALLINT NameLength3, SQLUSMALLINT Scope,
SQLUSMALLINT Nullable)
{
RETCODE ret;
char *ctName, *scName, *tbName;
UInt4 nmlen1, nmlen2, nmlen3;
mylog("[SQLSpecialColumnsW]");
ctName = ucs2_to_utf8(CatalogName, NameLength1, &nmlen1);
scName = ucs2_to_utf8(SchemaName, NameLength2, &nmlen2);
tbName = ucs2_to_utf8(TableName, NameLength3, &nmlen3);
ret = PGAPI_SpecialColumns(StatementHandle, IdentifierType, ctName,
(SWORD) nmlen1, scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3,
Scope, Nullable);
if (ctName);
free(ctName);
if (scName);
free(scName);
if (tbName);
free(tbName);
return ret;
}
RETCODE SQL_API SQLStatisticsW(HSTMT StatementHandle,
SQLWCHAR *CatalogName, SQLSMALLINT NameLength1,
SQLWCHAR *SchemaName, SQLSMALLINT NameLength2,
SQLWCHAR *TableName, SQLSMALLINT NameLength3,
SQLUSMALLINT Unique, SQLUSMALLINT Reserved)
{
RETCODE ret;
char *ctName, *scName, *tbName;
UInt4 nmlen1, nmlen2, nmlen3;
mylog("[SQLStatisticsW]");
ctName = ucs2_to_utf8(CatalogName, NameLength1, &nmlen1);
scName = ucs2_to_utf8(SchemaName, NameLength2, &nmlen2);
tbName = ucs2_to_utf8(TableName, NameLength3, &nmlen3);
return PGAPI_Statistics(StatementHandle, ctName, (SWORD) nmlen1,
scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3, Unique,
Reserved);
if (ctName);
free(ctName);
if (scName);
free(scName);
if (tbName);
free(tbName);
return ret;
}
RETCODE SQL_API SQLTablesW(HSTMT StatementHandle,
SQLWCHAR *CatalogName, SQLSMALLINT NameLength1,
SQLWCHAR *SchemaName, SQLSMALLINT NameLength2,
SQLWCHAR *TableName, SQLSMALLINT NameLength3,
SQLWCHAR *TableType, SQLSMALLINT NameLength4)
{
RETCODE ret;
char *ctName, *scName, *tbName, *tbType;
UInt4 nmlen1, nmlen2, nmlen3, nmlen4;
mylog("[SQLTablesW]");
ctName = ucs2_to_utf8(CatalogName, NameLength1, &nmlen1);
scName = ucs2_to_utf8(SchemaName, NameLength2, &nmlen2);
tbName = ucs2_to_utf8(TableName, NameLength3, &nmlen3);
tbType = ucs2_to_utf8(TableType, NameLength4, &nmlen4);
return PGAPI_Tables(StatementHandle, ctName, (SWORD) nmlen1,
scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3,
tbType, (SWORD) nmlen4);
if (ctName);
free(ctName);
if (scName);
free(scName);
if (tbName);
free(tbName);
if (tbType);
free(tbType);
return ret;
}
RETCODE SQL_API SQLColumnPrivilegesW(
HSTMT hstmt,
SQLWCHAR *szCatalogName,
SQLSMALLINT cbCatalogName,
SQLWCHAR *szSchemaName,
SQLSMALLINT cbSchemaName,
SQLWCHAR *szTableName,
SQLSMALLINT cbTableName,
SQLWCHAR *szColumnName,
SQLSMALLINT cbColumnName)
{
RETCODE ret;
char *ctName, *scName, *tbName, *clName;
UInt4 nmlen1, nmlen2, nmlen3, nmlen4;
mylog("[SQLColumnPrivilegesW]");
ctName = ucs2_to_utf8(szCatalogName, cbCatalogName, &nmlen1);
scName = ucs2_to_utf8(szSchemaName, cbSchemaName, &nmlen2);
tbName = ucs2_to_utf8(szTableName, cbTableName, &nmlen3);
clName = ucs2_to_utf8(szColumnName, cbColumnName, &nmlen4);
ret = PGAPI_ColumnPrivileges(hstmt, ctName, (SWORD) nmlen1,
scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3,
clName, (SWORD) nmlen4);
if (ctName);
free(ctName);
if (scName);
free(scName);
if (tbName);
free(tbName);
if (clName);
free(clName);
return ret;
}
RETCODE SQL_API SQLForeignKeysW(
HSTMT hstmt,
SQLWCHAR *szPkCatalogName,
SQLSMALLINT cbPkCatalogName,
SQLWCHAR *szPkSchemaName,
SQLSMALLINT cbPkSchemaName,
SQLWCHAR *szPkTableName,
SQLSMALLINT cbPkTableName,
SQLWCHAR *szFkCatalogName,
SQLSMALLINT cbFkCatalogName,
SQLWCHAR *szFkSchemaName,
SQLSMALLINT cbFkSchemaName,
SQLWCHAR *szFkTableName,
SQLSMALLINT cbFkTableName)
{
RETCODE ret;
char *ctName, *scName, *tbName, *fkctName, *fkscName, *fktbName;
UInt4 nmlen1, nmlen2, nmlen3, nmlen4, nmlen5, nmlen6;
mylog("[SQLForeignKeysW]");
ctName = ucs2_to_utf8(szPkCatalogName, cbPkCatalogName, &nmlen1);
scName = ucs2_to_utf8(szPkSchemaName, cbPkSchemaName, &nmlen2);
tbName = ucs2_to_utf8(szPkTableName, cbPkTableName, &nmlen3);
fkctName = ucs2_to_utf8(szFkCatalogName, cbFkCatalogName, &nmlen4);
fkscName = ucs2_to_utf8(szFkSchemaName, cbFkSchemaName, &nmlen5);
fktbName = ucs2_to_utf8(szFkTableName, cbFkTableName, &nmlen6);
ret = PGAPI_ForeignKeys(hstmt, ctName, (SWORD) nmlen1,
scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3,
fkctName, (SWORD) nmlen4, fkscName, (SWORD) nmlen5,
fktbName, (SWORD) nmlen6);
if (ctName);
free(ctName);
if (scName);
free(scName);
if (tbName);
free(tbName);
if (fkctName);
free(fkctName);
if (fkscName);
free(fkscName);
if (fktbName);
free(fktbName);
return ret;
}
RETCODE SQL_API SQLNativeSqlW(
HDBC hdbc,
SQLWCHAR *szSqlStrIn,
SQLINTEGER cbSqlStrIn,
SQLWCHAR *szSqlStr,
SQLINTEGER cbSqlStrMax,
SQLINTEGER *pcbSqlStr)
{
RETCODE ret;
char *szIn, *szOut;
UInt4 slen;
SQLINTEGER olen;
mylog("[SQLNativeSqlW]");
((ConnectionClass *) hdbc)->unicode = 1;
szIn = ucs2_to_utf8(szSqlStrIn, cbSqlStrIn, &slen);
szOut = malloc(cbSqlStrMax);
ret = PGAPI_NativeSql(hdbc, szIn, (SQLINTEGER) slen,
szOut, cbSqlStrMax, &olen);
if (szIn);
free(szIn);
*pcbSqlStr = utf8_to_ucs2(szOut, olen, szSqlStr, cbSqlStrMax);
free(szOut);
return ret;
}
RETCODE SQL_API SQLPrimaryKeysW(
HSTMT hstmt,
SQLWCHAR *szCatalogName,
SQLSMALLINT cbCatalogName,
SQLWCHAR *szSchemaName,
SQLSMALLINT cbSchemaName,
SQLWCHAR *szTableName,
SQLSMALLINT cbTableName)
{
RETCODE ret;
char *ctName, *scName, *tbName;
UInt4 nmlen1, nmlen2, nmlen3;
mylog("[SQLPrimaryKeysW]");
ctName = ucs2_to_utf8(szCatalogName, cbCatalogName, &nmlen1);
scName = ucs2_to_utf8(szSchemaName, cbSchemaName, &nmlen2);
tbName = ucs2_to_utf8(szTableName, cbTableName, &nmlen3);
return PGAPI_PrimaryKeys(hstmt, ctName, (SWORD) nmlen1,
scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3);
if (ctName);
free(ctName);
if (scName);
free(scName);
if (tbName);
free(tbName);
return ret;
}
RETCODE SQL_API SQLProcedureColumnsW(
HSTMT hstmt,
SQLWCHAR *szCatalogName,
SQLSMALLINT cbCatalogName,
SQLWCHAR *szSchemaName,
SQLSMALLINT cbSchemaName,
SQLWCHAR *szProcName,
SQLSMALLINT cbProcName,
SQLWCHAR *szColumnName,
SQLSMALLINT cbColumnName)
{
RETCODE ret;
char *ctName, *scName, *prName, *clName;
UInt4 nmlen1, nmlen2, nmlen3, nmlen4;
mylog("[SQLProcedureColumnsW]");
ctName = ucs2_to_utf8(szCatalogName, cbCatalogName, &nmlen1);
scName = ucs2_to_utf8(szSchemaName, cbSchemaName, &nmlen2);
prName = ucs2_to_utf8(szProcName, cbProcName, &nmlen3);
clName = ucs2_to_utf8(szColumnName, cbColumnName, &nmlen4);
ret = PGAPI_ProcedureColumns(hstmt, ctName, (SWORD) nmlen1,
scName, (SWORD) nmlen2, prName, (SWORD) nmlen3,
clName, (SWORD) nmlen4);
if (ctName);
free(ctName);
if (scName);
free(scName);
if (prName);
free(prName);
if (clName);
free(clName);
return ret;
}
RETCODE SQL_API SQLProceduresW(
HSTMT hstmt,
SQLWCHAR *szCatalogName,
SQLSMALLINT cbCatalogName,
SQLWCHAR *szSchemaName,
SQLSMALLINT cbSchemaName,
SQLWCHAR *szProcName,
SQLSMALLINT cbProcName)
{
RETCODE ret;
char *ctName, *scName, *prName;
UInt4 nmlen1, nmlen2, nmlen3;
mylog("[SQLProceduresW]");
ctName = ucs2_to_utf8(szCatalogName, cbCatalogName, &nmlen1);
scName = ucs2_to_utf8(szSchemaName, cbSchemaName, &nmlen2);
prName = ucs2_to_utf8(szProcName, cbProcName, &nmlen3);
ret = PGAPI_Procedures(hstmt, ctName, (SWORD) nmlen1,
scName, (SWORD) nmlen2, prName, (SWORD) nmlen3);
if (ctName);
free(ctName);
if (scName);
free(scName);
if (prName);
free(prName);
return ret;
}
RETCODE SQL_API SQLTablePrivilegesW(
HSTMT hstmt,
SQLWCHAR *szCatalogName,
SQLSMALLINT cbCatalogName,
SQLWCHAR *szSchemaName,
SQLSMALLINT cbSchemaName,
SQLWCHAR *szTableName,
SQLSMALLINT cbTableName)
{
RETCODE ret;
char *ctName, *scName, *tbName;
UInt4 nmlen1, nmlen2, nmlen3;
mylog("[SQLTablePrivilegesW]");
ctName = ucs2_to_utf8(szCatalogName, cbCatalogName, &nmlen1);
scName = ucs2_to_utf8(szSchemaName, cbSchemaName, &nmlen2);
tbName = ucs2_to_utf8(szTableName, cbTableName, &nmlen3);
ret = PGAPI_TablePrivileges(hstmt, ctName, (SWORD) nmlen1,
scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3, 0);
if (ctName);
free(ctName);
if (scName);
free(scName);
if (tbName);
free(tbName);
return ret;
}
/*-------
* Module: pgapi30.c
*
* Description: This module contains routines related to ODBC 3.0
* most of their implementations are temporary
* and must be rewritten properly.
* 2001/07/23 inoue
*
* Classes: n/a
*
* API functions: PGAPI_ColAttribute, PGAPI_GetDiagRec,
PGAPI_GetConnectAttr, PGAPI_GetStmtAttr,
PGAPI_SetConnectAttr, PGAPI_SetStmtAttr
*-------
*/
#ifndef ODBCVER
#define ODBCVER 0x0300
#endif
#include "psqlodbc.h"
#include <stdio.h>
#include <string.h>
#include "environ.h"
#include "connection.h"
#include "statement.h"
#include "pgapifunc.h"
/* SQLError -> SQLDiagRec */
RETCODE SQL_API
PGAPI_GetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
SQLSMALLINT RecNumber, SQLCHAR *Sqlstate,
SQLINTEGER *NativeError, SQLCHAR *MessageText,
SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
{
RETCODE ret;
static const char *func = "PGAPI_GetDiagRec";
mylog("%s entering ", func);
switch (HandleType)
{
case SQL_HANDLE_ENV:
ret = PGAPI_Error(Handle, NULL, NULL, Sqlstate, NativeError,
MessageText, BufferLength, TextLength);
break;
case SQL_HANDLE_DBC:
ret = PGAPI_Error(NULL, Handle, NULL, Sqlstate, NativeError,
MessageText, BufferLength, TextLength);
break;
case SQL_HANDLE_STMT:
ret = PGAPI_Error(NULL, NULL, Handle, Sqlstate, NativeError,
MessageText, BufferLength, TextLength);
break;
default:
ret = SQL_ERROR;
}
if (ret == SQL_SUCCESS_WITH_INFO &&
BufferLength == 0 &&
*TextLength)
{
SQLSMALLINT BufferLength = *TextLength + 4;
SQLCHAR *MessageText = malloc(BufferLength);
ret = PGAPI_GetDiagRec(HandleType, Handle, RecNumber, Sqlstate,
NativeError, MessageText, BufferLength,
TextLength);
free(MessageText);
}
mylog("%s exiting\n", func);
return ret;
}
/* SQLGetConnectOption -> SQLGetconnectAttr */
RETCODE SQL_API
PGAPI_GetConnectAttr(HDBC ConnectionHandle,
SQLINTEGER Attribute, PTR Value,
SQLINTEGER BufferLength, SQLINTEGER *StringLength)
{
ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
mylog("PGAPI_GetConnectAttr %d\n", Attribute);
switch (Attribute)
{
case SQL_ATTR_ASYNC_ENABLE:
case SQL_ATTR_AUTO_IPD:
case SQL_ATTR_CONNECTION_DEAD:
case SQL_ATTR_CONNECTION_TIMEOUT:
case SQL_ATTR_METADATA_ID:
conn->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
conn->errormsg = "Unsupported connection option (Set)";
return SQL_ERROR;
}
return PGAPI_GetConnectOption(ConnectionHandle, (UWORD) Attribute, Value);
}
static HSTMT
descHandleFromStatementHandle(HSTMT StatementHandle, SQLINTEGER descType)
{
switch (descType)
{
case SQL_ATTR_APP_ROW_DESC: /* 10010 */
return StatementHandle; /* this is bogus */
case SQL_ATTR_APP_PARAM_DESC: /* 10011 */
return (HSTMT) ((SQLUINTEGER) StatementHandle + 1) ; /* this is bogus */
case SQL_ATTR_IMP_ROW_DESC: /* 10012 */
return (HSTMT) ((SQLUINTEGER) StatementHandle + 2); /* this is bogus */
case SQL_ATTR_IMP_PARAM_DESC: /* 10013 */
return (HSTMT) ((SQLUINTEGER) StatementHandle + 3); /* this is bogus */
}
return (HSTMT) 0;
}
static HSTMT
statementHandleFromDescHandle(HSTMT DescHandle, SQLINTEGER *descType)
{
SQLUINTEGER res = (SQLUINTEGER) DescHandle % 4;
switch (res)
{
case 0: *descType = SQL_ATTR_APP_ROW_DESC; /* 10010 */
break;
case 1: *descType = SQL_ATTR_APP_PARAM_DESC; /* 10011 */
break;
case 2: *descType = SQL_ATTR_IMP_ROW_DESC; /* 10012 */
break;
case 3: *descType = SQL_ATTR_IMP_PARAM_DESC; /* 10013 */
break;
}
return (HSTMT) ((SQLUINTEGER) DescHandle - res);
}
static RETCODE SQL_API
ARDSetField(StatementClass *stmt, SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength)
{
RETCODE ret = SQL_SUCCESS;
PTR tptr;
switch (FieldIdentifier)
{
case SQL_DESC_ARRAY_SIZE:
stmt->options.rowset_size = (SQLUINTEGER) Value;
break;
case SQL_DESC_ARRAY_STATUS_PTR:
stmt->options.row_operation_ptr = Value;
break;
case SQL_DESC_BIND_OFFSET_PTR:
stmt->options.row_offset_ptr = Value;
break;
case SQL_DESC_BIND_TYPE:
stmt->options.bind_size = (SQLUINTEGER) Value;
break;
case SQL_DESC_DATA_PTR:
if (!RecNumber)
stmt->bookmark.buffer = Value;
else
stmt->bindings[RecNumber - 1].buffer = Value;
break;
case SQL_DESC_INDICATOR_PTR:
if (!RecNumber)
tptr = stmt->bookmark.used;
else
tptr = stmt->bindings[RecNumber - 1].used;
if (Value != tptr)
{
ret = SQL_ERROR;
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
stmt->errormsg = "INDICATOR != OCTET_LENGTH_PTR";
}
break;
case SQL_DESC_OCTET_LENGTH_PTR:
if (!RecNumber)
stmt->bookmark.used = Value;
else
stmt->bindings[RecNumber - 1].used = Value;
break;
default:ret = SQL_ERROR;
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
stmt->errormsg = "not implemedted yet";
}
return ret;
}
static RETCODE SQL_API
APDSetField(StatementClass *stmt, SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength)
{
RETCODE ret = SQL_SUCCESS;
switch (FieldIdentifier)
{
case SQL_DESC_ARRAY_SIZE:
stmt->options.paramset_size = (SQLUINTEGER) Value;
break;
case SQL_DESC_ARRAY_STATUS_PTR:
stmt->options.param_operation_ptr = Value;
break;
case SQL_DESC_BIND_OFFSET_PTR:
stmt->options.param_offset_ptr = Value;
break;
case SQL_DESC_BIND_TYPE:
stmt->options.param_bind_type = (SQLUINTEGER) Value;
break;
case SQL_DESC_DATA_PTR:
if (stmt->parameters_allocated < RecNumber)
PGAPI_BindParameter(stmt, RecNumber, 0, 0, 0, 0, 0, 0, 0, 0);
stmt->parameters[RecNumber - 1].buffer = Value;
break;
case SQL_DESC_INDICATOR_PTR:
if (stmt->parameters_allocated < RecNumber ||
Value != stmt->parameters[RecNumber - 1].used)
{
ret = SQL_ERROR;
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
stmt->errormsg = "INDICATOR != OCTET_LENGTH_PTR";
}
break;
case SQL_DESC_OCTET_LENGTH_PTR:
if (stmt->parameters_allocated < RecNumber)
PGAPI_BindParameter(stmt, RecNumber, 0, 0, 0, 0, 0, 0, 0, 0);
stmt->parameters[RecNumber - 1].used = Value;
break;
default:ret = SQL_ERROR;
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
}
return ret;
}
static RETCODE SQL_API
IRDSetField(StatementClass *stmt, SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength)
{
RETCODE ret = SQL_SUCCESS;
switch (FieldIdentifier)
{
case SQL_DESC_ARRAY_STATUS_PTR:
stmt->options.rowStatusArray = (SQLUSMALLINT *) Value;
break;
case SQL_DESC_ROWS_PROCESSED_PTR:
stmt->options.rowsFetched = (SQLUINTEGER *) Value;
break;
default:ret = SQL_ERROR;
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
}
return ret;
}
static RETCODE SQL_API
IPDSetField(StatementClass *stmt, SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength)
{
RETCODE ret = SQL_SUCCESS;
switch (FieldIdentifier)
{
case SQL_DESC_ARRAY_STATUS_PTR:
stmt->options.param_status_ptr = (SQLUSMALLINT *) Value;
break;
case SQL_DESC_ROWS_PROCESSED_PTR:
stmt->options.param_processed_ptr = (SQLUINTEGER *) Value;
break;
default:ret = SQL_ERROR;
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
}
return ret;
}
/* SQLGetStmtOption -> SQLGetStmtAttr */
RETCODE SQL_API
PGAPI_GetStmtAttr(HSTMT StatementHandle,
SQLINTEGER Attribute, PTR Value,
SQLINTEGER BufferLength, SQLINTEGER *StringLength)
{
static char *func = "PGAPI_GetStmtAttr";
StatementClass *stmt = (StatementClass *) StatementHandle;
RETCODE ret = SQL_SUCCESS;
int len = 0;
mylog("%s Handle=%u %d\n", func, StatementHandle, Attribute);
switch (Attribute)
{
case SQL_ATTR_FETCH_BOOKMARK_PTR: /* 16 */
Value = stmt->options.bookmark_ptr;
len = 4;
break;
case SQL_ATTR_PARAM_BIND_OFFSET_PTR: /* 17 */
Value = stmt->options.param_offset_ptr;
len = 4;
break;
case SQL_ATTR_PARAM_BIND_TYPE: /* 18 */
*((SQLUINTEGER *) Value) = stmt->options.param_bind_type;
len = 4;
break;
case SQL_ATTR_PARAM_OPERATION_PTR: /* 19 */
Value = stmt->options.param_operation_ptr;
len = 4;
break;
case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
Value = stmt->options.param_status_ptr;
len = 4;
break;
case SQL_ATTR_PARAMS_PROCESSED_PTR: /* 21 */
Value = stmt->options.param_processed_ptr;
len = 4;
break;
case SQL_ATTR_PARAMSET_SIZE: /* 22 */
*((SQLUINTEGER *) Value) = stmt->options.paramset_size;
len = 4;
break;
case SQL_ATTR_ROW_BIND_OFFSET_PTR: /* 23 */
Value = stmt->options.row_offset_ptr;
len = 4;
break;
case SQL_ATTR_ROW_OPERATION_PTR: /* 24 */
Value = stmt->options.row_operation_ptr;
len = 4;
break;
case SQL_ATTR_ROW_STATUS_PTR: /* 25 */
Value = stmt->options.rowStatusArray;
len = 4;
break;
case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */
Value = stmt->options.rowsFetched;
len = 4;
break;
case SQL_ATTR_ROW_ARRAY_SIZE: /* 27 */
*((SQLUINTEGER *) Value) = stmt->options.rowset_size;
len = 4;
break;
case SQL_ATTR_APP_ROW_DESC: /* 10010 */
case SQL_ATTR_APP_PARAM_DESC: /* 10011 */
case SQL_ATTR_IMP_ROW_DESC: /* 10012 */
case SQL_ATTR_IMP_PARAM_DESC: /* 10013 */
len = 4;
*((HSTMT *) Value) = descHandleFromStatementHandle(StatementHandle, Attribute);
break;
case SQL_ATTR_AUTO_IPD: /* 10001 */
/* case SQL_ATTR_ROW_BIND_TYPE: ** == SQL_BIND_TYPE(ODBC2.0) */
case SQL_ATTR_CURSOR_SCROLLABLE: /* -1 */
case SQL_ATTR_CURSOR_SENSITIVITY: /* -2 */
case SQL_ATTR_ENABLE_AUTO_IPD: /* 15 */
case SQL_ATTR_METADATA_ID: /* 10014 */
/*
* case SQL_ATTR_PREDICATE_PTR: case
* SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR:
*/
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
stmt->errormsg = "Unsupported statement option (Get)";
SC_log_error(func, "", stmt);
return SQL_ERROR;
default:
len = 4;
ret = PGAPI_GetStmtOption(StatementHandle, (UWORD) Attribute, Value);
}
if (ret == SQL_SUCCESS && StringLength)
*StringLength = len;
return ret;
}
/* SQLSetConnectOption -> SQLSetConnectAttr */
RETCODE SQL_API
PGAPI_SetConnectAttr(HDBC ConnectionHandle,
SQLINTEGER Attribute, PTR Value,
SQLINTEGER StringLength)
{
ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
mylog("PGAPI_SetConnectAttr %d\n", Attribute);
switch (Attribute)
{
case SQL_ATTR_ASYNC_ENABLE:
case SQL_ATTR_AUTO_IPD:
case SQL_ATTR_CONNECTION_DEAD:
case SQL_ATTR_CONNECTION_TIMEOUT:
case SQL_ATTR_METADATA_ID:
conn->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
conn->errormsg = "Unsupported connection option (Set)";
return SQL_ERROR;
}
return PGAPI_SetConnectOption(ConnectionHandle, (UWORD) Attribute, (UDWORD) Value);
}
/* new function */
RETCODE SQL_API
PGAPI_SetDescField(SQLHDESC DescriptorHandle,
SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
PTR Value, SQLINTEGER BufferLength)
{
RETCODE ret = SQL_SUCCESS;
HSTMT hstmt;
SQLUINTEGER descType;
StatementClass *stmt;
static const char *func = "PGAPI_SetDescField";
mylog("%s h=%u rec=%d field=%d val=%x\n", func, DescriptorHandle, RecNumber, FieldIdentifier, Value);
hstmt = statementHandleFromDescHandle(DescriptorHandle, &descType);
mylog("stmt=%x type=%d\n", hstmt, descType);
stmt = (StatementClass *) hstmt;
switch (descType)
{
case SQL_ATTR_APP_ROW_DESC:
ret = ARDSetField(stmt, RecNumber, FieldIdentifier, Value, BufferLength);
break;
case SQL_ATTR_APP_PARAM_DESC:
ret = APDSetField(stmt, RecNumber, FieldIdentifier, Value, BufferLength);
break;
case SQL_ATTR_IMP_ROW_DESC:
ret = IRDSetField(stmt, RecNumber, FieldIdentifier, Value, BufferLength);
break;
case SQL_ATTR_IMP_PARAM_DESC:
ret = IPDSetField(stmt, RecNumber, FieldIdentifier, Value, BufferLength);
break;
default:ret = SQL_ERROR;
stmt->errornumber = STMT_INTERNAL_ERROR;
stmt->errormsg = "Error not implemented";
}
if (ret == SQL_ERROR)
SC_log_error(func, "", stmt);
return ret;
}
/* SQLSet(Param/Scroll/Stmt)Option -> SQLSetStmtAttr */
RETCODE SQL_API
PGAPI_SetStmtAttr(HSTMT StatementHandle,
SQLINTEGER Attribute, PTR Value,
SQLINTEGER StringLength)
{
static char *func = "PGAPI_SetStmtAttr";
StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("%s Handle=%u %d,%u\n", func, StatementHandle, Attribute, Value);
switch (Attribute)
{
case SQL_ATTR_CURSOR_SCROLLABLE: /* -1 */
case SQL_ATTR_CURSOR_SENSITIVITY: /* -2 */
case SQL_ATTR_ENABLE_AUTO_IPD: /* 15 */
case SQL_ATTR_APP_ROW_DESC: /* 10010 */
case SQL_ATTR_APP_PARAM_DESC: /* 10011 */
case SQL_ATTR_AUTO_IPD: /* 10001 */
/* case SQL_ATTR_ROW_BIND_TYPE: ** == SQL_BIND_TYPE(ODBC2.0) */
case SQL_ATTR_IMP_ROW_DESC: /* 10012 (read-only) */
case SQL_ATTR_IMP_PARAM_DESC: /* 10013 (read-only) */
case SQL_ATTR_METADATA_ID: /* 10014 */
/*
* case SQL_ATTR_PREDICATE_PTR: case
* SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR:
*/
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
stmt->errormsg = "Unsupported statement option (Set)";
SC_log_error(func, "", stmt);
return SQL_ERROR;
case SQL_ATTR_FETCH_BOOKMARK_PTR: /* 16 */
stmt->options.bookmark_ptr = Value;
break;
case SQL_ATTR_PARAM_BIND_OFFSET_PTR: /* 17 */
stmt->options.param_offset_ptr = (SQLUINTEGER *) Value;
break;
case SQL_ATTR_PARAM_BIND_TYPE: /* 18 */
stmt->options.param_bind_type = (SQLUINTEGER) Value;
break;
case SQL_ATTR_PARAM_OPERATION_PTR: /* 19 */
stmt->options.param_operation_ptr = Value;
break;
case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
stmt->options.param_status_ptr = (SQLUSMALLINT *) Value;
break;
case SQL_ATTR_PARAMS_PROCESSED_PTR: /* 21 */
stmt->options.param_processed_ptr = (SQLUINTEGER *) Value;
break;
case SQL_ATTR_PARAMSET_SIZE: /* 22 */
stmt->options.paramset_size = (SQLUINTEGER) Value;
break;
case SQL_ATTR_ROW_BIND_OFFSET_PTR: /* 23 */
stmt->options.row_offset_ptr = (SQLUINTEGER *) Value;
break;
case SQL_ATTR_ROW_OPERATION_PTR: /* 24 */
stmt->options.row_operation_ptr = Value;
break;
case SQL_ATTR_ROW_STATUS_PTR: /* 25 */
stmt->options.rowStatusArray = (SQLUSMALLINT *) Value;
break;
case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */
stmt->options.rowsFetched = (SQLUINTEGER *) Value;
break;
case SQL_ATTR_ROW_ARRAY_SIZE: /* 27 */
stmt->options.rowset_size = (SQLUINTEGER) Value;
break;
default:
return PGAPI_SetStmtOption(StatementHandle, (UWORD) Attribute, (UDWORD) Value);
}
return SQL_SUCCESS;
}
/*-------
* Module: win_unicode.c
*
* Description: This module contains utf8 <-> ucs2 conversion routines
* under WIndows
*
*-------
*/
#include "psqlodbc.h"
#include <stdio.h>
#include <string.h>
#define byte3check 0xf800
#define byte2_base 0x80c0
#define byte2_mask1 0x07c0
#define byte2_mask2 0x003f
#define byte3_base 0x8080e0
#define byte3_mask1 0xf000
#define byte3_mask2 0x0fc0
#define byte3_mask3 0x003f
char *ucs2_to_utf8(const SQLWCHAR *ucs2str, Int4 ilen, UInt4 *olen)
{
char * utf8str;
/*mylog("ucs2_to_utf8 %x ilen=%d ", ucs2str, ilen);*/
if (!ucs2str)
return NULL;
if (ilen < 0)
{
for (ilen = 0; ucs2str[ilen]; ilen++)
;
}
/*mylog(" newlen=%d", ilen);*/
utf8str = (char *) malloc(ilen * 3 + 1);
if (utf8str)
{
int i, len = 0;
Int2 byte2code;
Int4 byte4code;
const SQLWCHAR *wstr;
for (i = 0, wstr = ucs2str; i < ilen; i++, wstr++)
{
if (!*wstr)
break;
else if (iswascii(*wstr))
utf8str[len++] = (char) *wstr;
else if ((*wstr & byte3check) == 0)
{
byte2code = byte2_base |
((byte2_mask1 & *wstr) >> 6) |
((byte2_mask2 & *wstr) << 8);
memcpy(utf8str + len, (char *) &byte2code, sizeof(byte2code));
len += 2;
}
else
{
byte4code = byte3_base |
((byte3_mask1 & *wstr) >> 12) |
((byte3_mask2 & *wstr) << 2) |
((byte3_mask3 & *wstr) << 16);
memcpy(utf8str + len, (char *) &byte4code, 3);
len += 3;
}
}
utf8str[len] = '\0';
*olen = len;
}
/*mylog(" olen=%d %s\n", *olen, utf8str ? utf8str : "");*/
return utf8str;
}
#define byte3_m1 0x0f
#define byte3_m2 0x3f
#define byte3_m3 0x3f
#define byte2_m1 0x1f
#define byte2_m2 0x3f
UInt4 utf8_to_ucs2(const char *utf8str, Int4 ilen, SQLWCHAR *ucs2str, UInt4 bufcount)
{
int i;
UInt4 ocount, wcode;
const unsigned char *str;
/*mylog("utf8_to_ucs2 ilen=%d bufcount=%d", ilen, bufcount);*/
if (!utf8str || !ilen)
return 0;
/*mylog(" string=%s\n", utf8str);*/
if (!bufcount)
ucs2str = NULL;
else if (!ucs2str)
bufcount = 0;
if (ilen < 0)
ilen = strlen(utf8str);
for (i = 0, ocount = 0, str = utf8str; i < ilen;)
{
if (iswascii(*str))
{
if (ocount < bufcount)
ucs2str[ocount] = *str;
ocount++;
i++;
str++;
}
else if (0xe0 == (*str & 0xe0)) /* 3 byte code */
{
if (ocount < bufcount)
{
wcode = ((((UInt4) *str) & byte3_m1) << 12) |
((((UInt4) str[1]) & byte3_m2) << 6) |
((UInt4) str[2]) & byte3_m3;
ucs2str[ocount] = (SQLWCHAR) wcode;
}
ocount++;
i += 3;
str += 3;
}
else
{
if (ocount < bufcount)
{
wcode = ((((UInt4) *str) & byte2_m1) << 6) |
((UInt4) str[1]) & byte2_m2;
ucs2str[ocount] = (SQLWCHAR) wcode;
}
ocount++;
i += 2;
str += 2;
}
}
if (ocount && ocount < bufcount && ucs2str)
ucs2str[ocount] = 0;
/*mylog(" ocount=%d\n", ocount);*/
return ocount;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment