/* Copyright (C) 1995-2005 MySQL AB

   This program is free software
{

} you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation
{

} either version 2 of the License, or
   (at your option) any later version.

   There are special exceptions to the terms and conditions of the GPL as it
   is applied to this software. View the full text of the exception in file
   EXCEPTIONS in the directory of this software distribution.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY
{

} without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program
{

} if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/***************************************************************************
 * UNICODE.C -   Unicode versions of some routines             *
 *                     *
 * @description: Unicode versions of some routines     *
 *                     *
 * @author     : MySQL AB(andrey@mysql.com)       *
 * @date       : 2005-Jun-13               *
 * @product    : myodbc3               *
 *                     *
 ****************************************************************************/

#include "myodbc3.h"
//#include "ConvertUTF.h"


/*
  length in chars
*/
unsigned int my_utf8_strlen(UTF8 *str, unsigned int buflen)
{
  UTF8 *p= str - 1;
  unsigned int c = 0;
  /*
  0xxx xxxx - 1 byte
  110x xxxx - 2 bytes
  1110 xxxx - 3 bytes
  1111 0xxx - 4 bytes
  */

  /* all non-chainheads start with sth different than 10 */
  while (*++p != 0 && buflen--)
    if ((*p >> 6) ^ 2)
      ++c;
  wprintf(L"my_utf8_strlen=%d\n", c);
  return c;
}

/*
  buflen is len in UTF8 not bytes
*/
unsigned int my_u8_buflen(UTF8 *str, unsigned int clen)
{
  UTF8 *p= str - 1;
  unsigned int c = 0;
  /*
  0xxx xxxx - 1 byte
  110x xxxx - 2 bytes
  1110 xxxx - 3 bytes
  1111 0xxx - 4 bytes
  */

  /* all non-chainheads start with sth different than 10 */
  while (*++p != 0 || clen)
    if ((*p >> 6) ^ 2)
    {
      clen--;
      if (*p < 128)
        c+= 1;
      else if (*p < 224)
        c+=2;
			else if (*p < 240)
        c+=3;
      else
        c+=4;
    }

  wprintf(L"my_u8_buflen=%d\n", c);
  return c;
}

/*
  buflen is len in UTF16 not bytes
*/
unsigned int my_u16_buflen(UTF16 *str, unsigned int clen)
{
  UTF16 *p= str;
  unsigned int c = 0;

  while (clen--)
  {
    if (*p < 0xD800)
      c+=1;
    else if (*p < 0xDC00)
      ;//error
    else if (*p < 0xE000)
    {
      c+=2;
      ++p;
    }
    ++p;
  }
  
  wprintf(L"my_u16_buflen=%d\n", c);
  return c;
}


/*
  in_len - number of codepoints (chars) and not bytes
  out_len - number of bytes in the output buffer

*/
    
MY_ConversionResult my_ConvertUTF16toUTF8(
    SQLWCHAR *source_start, SQLINTEGER in_len, 
    UTF8** target_start, SQLUINTEGER *out_len, SQLUINTEGER *out_char_len)
{
  ConversionResult res;
  UTF8 *out_buf_start;
  UTF16 *in_buf_start= (UTF16 *) source_start;
  unsigned int u8_buf_len = 0, u16_buf_len;
  DBUG_ENTER("my_ConvertUTF16toUTF8");
  
  if (res = u16_to_u8_length(source_start, source_start + (u16_buf_len = my_u16_buflen(in_buf_start, in_len)), &u8_buf_len))
    DBUG_RETURN(res);

  wprintf(L"[%s::%d]\n", __FILE__, __LINE__);

  if (!(*target_start = out_buf_start = (UTF8 *) my_malloc(u8_buf_len + 1, MYF(0))))
    DBUG_RETURN(my_outOfMemory);

  res= ConvertUTF16toUTF8(
            (const UTF16 **) &in_buf_start,
             in_buf_start + u16_buf_len,
             &out_buf_start,
             out_buf_start + u8_buf_len,
             strictConversion
          );

  (*target_start)[u8_buf_len]= 0;
  /* overflow should not happen at all*/
  if (res)
    my_free((gptr) *target_start, MYF(0));
  else
  {
    if (out_len)
      *out_len= u8_buf_len;
    if (out_char_len)
      *out_char_len= in_len;
  }

  wprintf(L"[%s::%d]\n", __FILE__, __LINE__);
  DBUG_RETURN(res);  
}


/*
  in_len - number of codepoints (chars) and not bytesu16_buf_len
  out_len - number of bytes in the output buffer

*/
MY_ConversionResult my_ConvertUTF8toUTF16 (
    UTF8 *source_start, SQLINTEGER in_len, 
    SQLWCHAR **target_start, SQLUINTEGER *out_len, SQLUINTEGER *out_char_len,
    SQLUINTEGER max_char_len)
{

  ConversionResult res;
  UTF8 *in_buf_start= source_start;
  unsigned int u16_buf_len=0, u8_buf_len, u8_str_len;
  DBUG_ENTER("my_ConvertUTF8toUTF16");

  wprintf(L"[%s::%d]\n", __FILE__, __LINE__);

  in_buf_start= source_start;
  u8_buf_len= in_len;
  u8_str_len= my_utf8_strlen(source_start, in_len);

  if (res = u8_to_u16_length(source_start, source_start + u8_buf_len, &u16_buf_len))
    DBUG_RETURN(res);
  
  if (((char *) target_start) + u16_buf_len > (char *)(target_start + max_char_len))
    DBUG_RETURN(my_targetExhausted);
  (*target_start)[u8_buf_len-1]= 0;

  res= ConvertUTF8toUTF16((const UTF8 **) &in_buf_start, in_buf_start + u8_buf_len,
               target_start, *target_start + u8_str_len,
               strictConversion, 
               NULL);
  if (!res)
  {
    if (out_len)
      *out_len= u16_buf_len;
    if (out_char_len)
      *out_char_len= in_len;
  }
  DBUG_RETURN(res);
}


SQLRETURN SQL_API SQLColAttributeW(
  SQLHSTMT    hstmt __attribute__((unused)),
  SQLUSMALLINT  iCol __attribute__((unused)),
  SQLUSMALLINT  iField __attribute__((unused)),
  SQLPOINTER    pCharAttr __attribute__((unused)),
  SQLSMALLINT    cbCharAttrMax __attribute__((unused)),  
  SQLSMALLINT  *pcbCharAttr __attribute__((unused)),
  SQLPOINTER    pNumAttr __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);
  
}

SQLRETURN SQL_API SQLColAttributesW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLUSMALLINT       icol __attribute__((unused)),
    SQLUSMALLINT       fDescType __attribute__((unused)),
    SQLPOINTER         rgbDesc __attribute__((unused)),
    SQLSMALLINT        cbDescMax __attribute__((unused)),
    SQLSMALLINT        *pcbDesc __attribute__((unused)),
    SQLLEN             *pfDesc __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);
  
}

SQLRETURN SQL_API my_SQLConnect(SQLHDBC hdbc, 
                             SQLCHAR FAR *szDSN,
                             SQLSMALLINT cbDSN,
                             SQLCHAR FAR *szUID, 
                             SQLSMALLINT cbUID,
                             SQLCHAR FAR *szAuthStr, 
                             SQLSMALLINT cbAuthStr, short is_utf8);

SQLRETURN SQL_API SQLConnectW(
    SQLHDBC            hdbc,
    SQLWCHAR        *szDSN,
    SQLSMALLINT        cbDSN,
    SQLWCHAR        *szUID,
    SQLSMALLINT        cbUID,
    SQLWCHAR        *szAuthStr,
    SQLSMALLINT        cbAuthStr)
{
  UTF8 *u8DSN= NULL, *u8UID= NULL, *u8AuthStr= NULL;
  SQLINTEGER dsn_len= 0, uid_len = 0, auth_len = 0;
  MY_ConversionResult res= my_conversionOK;
  SQLRETURN res2;
  DBUG_ENTER("SQLConnectW");
  
  wprintf(L"[cbDSN=%d][cbUID=%d][cvAuthStr=%d]", cbDSN, cbUID, cbAuthStr);

  if (cbDSN == SQL_NTS || cbUID == SQL_NTS || cbAuthStr == SQL_NTS)
    DBUG_RETURN_STATUS(SQL_ERROR);// when using utf-16 one cannot calculate easily the len
  wprintf(L"[%s::%d]\n", __FILE__, __LINE__);
  
  u8DSN= u8UID= u8AuthStr= NULL;
  if (szDSN && (res= my_ConvertUTF16toUTF8(szDSN, cbDSN, &u8DSN, &dsn_len, NULL)))
    goto error_clean;
  if (szUID && (res= my_ConvertUTF16toUTF8(szUID, cbUID, &u8UID, &uid_len, NULL)))
    goto error_clean;
  if (szAuthStr && (res= my_ConvertUTF16toUTF8(szAuthStr, cbAuthStr, &u8AuthStr, &auth_len, NULL)))
    goto error_clean;
  
  res2 = my_SQLConnect(hdbc, (SQLCHAR*) u8DSN, dsn_len, (SQLCHAR*) u8UID,
                  uid_len, (SQLCHAR*)u8AuthStr, auth_len, 1);

  wprintf(L"[%s::%d]\n", __FILE__, __LINE__);

error_clean:
  if (res)
  {
    res2= SQL_ERROR;
    DBUG_PRINT("SQLConnectW", ("error while converting to utf-8"));
  }
  if (u8DSN)
    my_free(u8DSN, MYF(0));
  if (u8UID)
    my_free(u8UID, MYF(0));
  if (u8AuthStr)
    my_free(u8AuthStr, MYF(0));
  
  DBUG_RETURN_STATUS(res2);   
}


SQLRETURN SQL_API SQLDescribeColW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLUSMALLINT       icol __attribute__((unused)),
    SQLWCHAR        *szColName __attribute__((unused)),
    SQLSMALLINT        cbColNameMax __attribute__((unused)),
    SQLSMALLINT    *pcbColName __attribute__((unused)),
    SQLSMALLINT    *pfSqlType __attribute__((unused)),
    SQLULEN       *pcbColDef __attribute__((unused)),
    SQLSMALLINT    *pibScale __attribute__((unused)),
    SQLSMALLINT    *pfNullable __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}


SQLRETURN SQL_API SQLError(
         SQLHENV        henv,
         SQLHDBC        hdbc,
         SQLHSTMT       hstmt,
         SQLCHAR FAR    *szSqlState,
         SQLINTEGER FAR *pfNativeError,
         SQLCHAR FAR    *szErrorMsg,
         SQLSMALLINT    cbErrorMsgMax,
         SQLSMALLINT FAR *pcbErrorMsg);

SQLRETURN SQL_API SQLErrorW(
    SQLHENV            henv __attribute__((unused)),
    SQLHDBC            hdbc __attribute__((unused)),
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLWCHAR        *szSqlState __attribute__((unused)),
    SQLINTEGER     *pfNativeError __attribute__((unused)),
    SQLWCHAR        *szErrorMsg __attribute__((unused)),
    SQLSMALLINT        cbErrorMsgMax __attribute__((unused)),
    SQLSMALLINT    *pcbErrorMsg __attribute__((unused)))
{
  DBUG_ENTER("SQLConnectW");
  
  DBUG_RETURN_STATUS(SQL_SUCCESS);   
}



SQLRETURN SQL_API SQLExecDirectW(
    SQLHSTMT           hstmt,
    SQLWCHAR        *szSqlStr,
    SQLINTEGER         cbSqlStr)
{
  int error;
  DBUG_ENTER("SQLExecDirectW");
  ((STMT FAR*) hstmt)->is_result_utf8= 1;

  if ((error= my_SQLPrepare(hstmt, (SQLCHAR *) szSqlStr, cbSqlStr)))
    DBUG_RETURN_STATUS(error);
  error= my_SQLExecute((STMT FAR*) hstmt);
  DBUG_RETURN_STATUS(error);
}


SQLRETURN SQL_API SQLGetConnectAttr(SQLHDBC hdbc,
            SQLINTEGER Attribute,
            SQLPOINTER ValuePtr,
            SQLINTEGER BufferLength,
            SQLINTEGER *StringLengthPtr);

SQLRETURN SQL_API SQLGetConnectAttrW(
    SQLHDBC            hdbc,
    SQLINTEGER         fAttribute,
    SQLPOINTER         rgbValue,
    SQLINTEGER         cbValueMax,
    SQLINTEGER         *pcbValue)
{
  ConversionResult res;
  UTF8* u8_buf;
  SQLUINTEGER u8_buf_len;
//  unsigned int u16_buf_len;
  SQLRETURN res2;
  DBUG_ENTER("SQLGetConnectAttrW");

  wprintf(L"[%s::%d]\n", __FILE__, __LINE__);
  if (fAttribute != SQL_ATTR_CURRENT_CATALOG)
    DBUG_RETURN_STATUS(SQLGetConnectAttr(hdbc, fAttribute, rgbValue, cbValueMax,
               pcbValue)
        );

  u8_buf= my_malloc(cbValueMax * 4 + 1, MYF(0));
  res2= SQLGetConnectAttr(hdbc, fAttribute, u8_buf, cbValueMax * 4, &u8_buf_len);
  if (res2 != SQL_SUCCESS && res2 != SQL_SUCCESS_WITH_INFO)
    DBUG_RETURN_STATUS(res2);
  u8_buf[u8_buf_len]= 0;

//  if (res = u8_to_u16_length(u8_buf, u8_buf + u8_buf_len, &u16_buf_len))
//    goto done;

  
  if (res= my_ConvertUTF8toUTF16(u8_buf, u8_buf_len, (SQLWCHAR **)&rgbValue, NULL/*buflen*/,
          (SQLINTEGER *)pcbValue, cbValueMax))
    goto done;

done:
  my_free(u8_buf, MYF(0));
  if (res)
    DBUG_RETURN_STATUS(SQL_ERROR);

  DBUG_RETURN_STATUS(SQL_SUCCESS);
}



SQLRETURN SQL_API SQLGetCursorNameW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLWCHAR        *szCursor __attribute__((unused)),
    SQLSMALLINT        cbCursorMax __attribute__((unused)),
    SQLSMALLINT    *pcbCursor __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}

#if (ODBCVER >= 0x0300)
SQLRETURN  SQL_API SQLSetDescFieldW(SQLHDESC DescriptorHandle __attribute__((unused)),
                          SQLSMALLINT RecNumber __attribute__((unused)), 
                   SQLSMALLINT FieldIdentifier __attribute__((unused)),
                          SQLPOINTER Value __attribute__((unused)), 
                   SQLINTEGER BufferLength __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);
}



SQLRETURN SQL_API SQLGetDescFieldW(
    SQLHDESC           hdesc __attribute__((unused)),
    SQLSMALLINT        iRecord __attribute__((unused)),
    SQLSMALLINT        iField __attribute__((unused)),
    SQLPOINTER         rgbValue __attribute__((unused)),
    SQLINTEGER       cbValueMax __attribute__((unused)),
    SQLINTEGER     *pcbValue __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}

SQLRETURN SQL_API SQLGetDescRecW(
    SQLHDESC           hdesc __attribute__((unused)),
    SQLSMALLINT        iRecord __attribute__((unused)),
    SQLWCHAR        *szName __attribute__((unused)),
    SQLSMALLINT        cbNameMax __attribute__((unused)),
    SQLSMALLINT    *pcbName __attribute__((unused)),
    SQLSMALLINT    *pfType __attribute__((unused)),
    SQLSMALLINT    *pfSubType __attribute__((unused)),
    SQLLEN         *pLength __attribute__((unused)),
    SQLSMALLINT    *pPrecision __attribute__((unused)), 
    SQLSMALLINT    *pScale __attribute__((unused)),
    SQLSMALLINT    *pNullable __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}

SQLRETURN SQL_API SQLGetDiagFieldW(
    SQLSMALLINT        fHandleType __attribute__((unused)),
    SQLHANDLE          handle __attribute__((unused)),
    SQLSMALLINT        iRecord __attribute__((unused)),
    SQLSMALLINT        fDiagField __attribute__((unused)),
    SQLPOINTER         rgbDiagInfo __attribute__((unused)),
    SQLSMALLINT        cbDiagInfoMax __attribute__((unused)),
    SQLSMALLINT    *pcbDiagInfo __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}

SQLRETURN my_SQLGetDiagRec(SQLSMALLINT HandleType,
			   SQLHANDLE Handle,
			   SQLSMALLINT RecNumber,
			   SQLCHAR *Sqlstate,
			   SQLINTEGER  *NativeErrorPtr,
			   SQLCHAR *MessageText,
			   SQLSMALLINT BufferLength,
			   SQLSMALLINT *TextLengthPtr);

SQLRETURN SQL_API SQLGetDiagRecW(
    SQLSMALLINT        fHandleType,
    SQLHANDLE          handle,
    SQLSMALLINT        iRecord,
    SQLWCHAR        *szSqlState,
    SQLINTEGER     *pfNativeError,
    SQLWCHAR        *szErrorMsg,
    SQLSMALLINT        cbErrorMsgMax,
    SQLSMALLINT    *pcbErrorMsg)
{
  DBUG_ENTER("SQLGetDiagRecW");

  /* not true unicode but for now works ! */
  DBUG_RETURN_STATUS(my_SQLGetDiagRec(fHandleType,handle,iRecord, (SQLCHAR *)szSqlState,
			  pfNativeError, (SQLCHAR *) szErrorMsg,
			  cbErrorMsgMax, pcbErrorMsg)
  );

}


#endif


SQLRETURN SQL_API SQLPrepareW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLWCHAR        *szSqlStr __attribute__((unused)),
    SQLINTEGER         cbSqlStr __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}


SQLRETURN SQL_API SQLSetConnectAttr(SQLHDBC hdbc,
            SQLINTEGER Attribute,
            SQLPOINTER ValuePtr,
            SQLINTEGER StringLength);

SQLRETURN SQL_API SQLSetConnectAttrW(
    SQLHDBC            hdbc,
    SQLINTEGER         fAttribute,
    SQLPOINTER         rgbValue,
    SQLINTEGER         cbValue)
{
  ConversionResult res= conversionOK;
  UTF8 *u8_value;
  unsigned int u8_buf_len;
  SQLINTEGER u8_buf_len_x;
  SQLRETURN res2 = SQL_SUCCESS;
  DBUG_ENTER("SQLSetConnectAttrW");

  wprintf(L"[%s::%d]\n", __FILE__, __LINE__);

  if (fAttribute != SQL_ATTR_CURRENT_CATALOG)
    DBUG_RETURN_STATUS(SQLSetConnectAttr(hdbc, fAttribute, rgbValue, cbValue));

  if (res = u16_to_u8_length(rgbValue, rgbValue + cbValue, (unsigned int *) &u8_buf_len))
    DBUG_RETURN(res);
    
  u8_buf_len_x = u8_buf_len;
  u8_value= my_malloc(u8_buf_len + 1, MYF(0));
  if (res= my_ConvertUTF16toUTF8(rgbValue, cbValue, &u8_value, NULL, NULL))
    goto error_clean;
  
  res2 = SQLSetConnectAttr(hdbc, fAttribute, u8_value, u8_buf_len_x);
  
error_clean:
  my_free(u8_value, MYF(0));

  if (res)
    DBUG_PRINT("SQLSetConnectAttrW", ("error while converting to utf-8"));

  if (res || res2 != SQL_SUCCESS)
    DBUG_RETURN_STATUS(SQL_ERROR);

  DBUG_RETURN_STATUS(SQL_SUCCESS);
}



SQLRETURN SQL_API SQLSetCursorNameW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLWCHAR        *szCursor __attribute__((unused)),
    SQLSMALLINT        cbCursor __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}

SQLRETURN SQL_API SQLColumnsW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLWCHAR        *szCatalogName __attribute__((unused)),
    SQLSMALLINT        cbCatalogName __attribute__((unused)),
    SQLWCHAR        *szSchemaName __attribute__((unused)),
    SQLSMALLINT        cbSchemaName __attribute__((unused)),
    SQLWCHAR        *szTableName __attribute__((unused)),
    SQLSMALLINT        cbTableName __attribute__((unused)),
    SQLWCHAR        *szColumnName __attribute__((unused)),
    SQLSMALLINT        cbColumnName __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}

SQLRETURN SQL_API SQLGetConnectOptionW(
    SQLHDBC            hdbc __attribute__((unused)),
    SQLUSMALLINT       fOption __attribute__((unused)),
    SQLPOINTER         pvParam __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}



SQLRETURN SQL_API SQLGetInfoW(
    SQLHDBC            hdbc __attribute__((unused)),
    SQLUSMALLINT       fInfoType __attribute__((unused)),
    SQLPOINTER         rgbInfoValue __attribute__((unused)),
    SQLSMALLINT        cbInfoValueMax __attribute__((unused)),
    SQLSMALLINT    *pcbInfoValue __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}

SQLRETURN SQL_API  SQLGetTypeInfoW(
  SQLHSTMT      StatementHandle __attribute__((unused)),
  SQLSMALLINT      DataType __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}


SQLRETURN SQL_API SQLSetConnectOptionW(
    SQLHDBC            hdbc __attribute__((unused)),
    SQLUSMALLINT       fOption __attribute__((unused)),
    SQLULEN            vParam __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}


SQLRETURN SQL_API SQLSpecialColumnsW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLUSMALLINT       fColType __attribute__((unused)),
    SQLWCHAR        *szCatalogName __attribute__((unused)),
    SQLSMALLINT        cbCatalogName __attribute__((unused)),
    SQLWCHAR        *szSchemaName __attribute__((unused)),
    SQLSMALLINT        cbSchemaName __attribute__((unused)),
    SQLWCHAR        *szTableName __attribute__((unused)),
    SQLSMALLINT        cbTableName __attribute__((unused)),
    SQLUSMALLINT       fScope __attribute__((unused)),
    SQLUSMALLINT       fNullable __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}

SQLRETURN SQL_API SQLStatisticsW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLWCHAR        *szCatalogName __attribute__((unused)),
    SQLSMALLINT        cbCatalogName __attribute__((unused)),
    SQLWCHAR        *szSchemaName __attribute__((unused)),
    SQLSMALLINT        cbSchemaName __attribute__((unused)),
    SQLWCHAR        *szTableName __attribute__((unused)),
    SQLSMALLINT        cbTableName __attribute__((unused)),
    SQLUSMALLINT       fUnique __attribute__((unused)),
    SQLUSMALLINT       fAccuracy __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}

SQLRETURN SQL_API SQLTablesW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLWCHAR        *szCatalogName __attribute__((unused)),
    SQLSMALLINT        cbCatalogName __attribute__((unused)),
    SQLWCHAR        *szSchemaName __attribute__((unused)),
    SQLSMALLINT        cbSchemaName __attribute__((unused)),
    SQLWCHAR        *szTableName __attribute__((unused)),
    SQLSMALLINT        cbTableName __attribute__((unused)),
    SQLWCHAR        *szTableType __attribute__((unused)),
    SQLSMALLINT        cbTableType __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}



SQLRETURN SQL_API SQLDataSourcesW(
    SQLHENV            henv __attribute__((unused)),
    SQLUSMALLINT       fDirection __attribute__((unused)),
    SQLWCHAR        *szDSN __attribute__((unused)),
    SQLSMALLINT        cbDSNMax __attribute__((unused)),
    SQLSMALLINT    *pcbDSN __attribute__((unused)),
    SQLWCHAR        *szDescription __attribute__((unused)),
    SQLSMALLINT        cbDescriptionMax __attribute__((unused)),
    SQLSMALLINT    *pcbDescription __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}


SQLRETURN SQL_API SQLDriverConnectW(
    SQLHDBC            hdbc,
    SQLHWND            hwnd,
    SQLWCHAR        *szConnStrIn,
    SQLSMALLINT        cbConnStrIn,
    SQLWCHAR        *szConnStrOut,
    SQLSMALLINT        cbConnStrOutMax,
    SQLSMALLINT    *pcbConnStrOut,
    SQLUSMALLINT       fDriverCompletion)
{
  UTF8 *u8_in_buf = NULL, *u8_out_buf = NULL;
  SQLUINTEGER u8_in_buf_len=0;
  SQLSMALLINT conn_str_out_len;
  MY_ConversionResult res;
  SQLRETURN res2;
  
  DBUG_ENTER("SQLDriverConnectW");
  wprintf(L"[%s::%d]\n", __FILE__, __LINE__);

  /* ok we convert the utf16 to utf8 to be used by SQLDriverConnect */
  if (res= my_ConvertUTF16toUTF8(szConnStrIn, cbConnStrIn, &u8_in_buf, &u8_in_buf_len, NULL/*charlen*/))
    goto error_clean;
  
  /*
  ok, let's allocate space for the out string of SQLDriverConnect, we cannot use
  the buffer provided by the user.
  */
  u8_out_buf= (UTF8 *) my_malloc(cbConnStrOutMax*4 + 1, MYF(0));//we don't know how much, then allocate at most
  

  res2 = my_SQLDriverConnect(hdbc, hwnd, u8_in_buf, u8_in_buf_len, u8_out_buf,
              cbConnStrOutMax*4, &conn_str_out_len, fDriverCompletion, 1);
  if (res2 != SQL_ERROR)
  {
    SQLUINTEGER temp_len;
    u8_out_buf[conn_str_out_len]= '\0';

    if (res= my_ConvertUTF8toUTF16(u8_out_buf, conn_str_out_len,
              &szConnStrOut, NULL/*buflen*/, &temp_len, cbConnStrOutMax))
      goto error_clean;  
    if (pcbConnStrOut)
      *pcbConnStrOut= temp_len;
  }  

error_clean:
  if (res)
  {
    res2= SQL_ERROR;
    DBUG_PRINT("SQLDriverConnectW", ("error while converting from utf-8"));
  }
  if (u8_in_buf)
    my_free(u8_in_buf, MYF(0));
  if (u8_out_buf)
    my_free(u8_out_buf, MYF(0));

  DBUG_RETURN_STATUS(res2);
}

SQLRETURN SQL_API
SQLBrowseConnect(
     SQLHDBC      hdbc,
     SQLCHAR FAR *szConnStrIn __attribute__((unused)),
     SQLSMALLINT cbConnStrIn __attribute__((unused)),
     SQLCHAR FAR *szConnStrOut __attribute__((unused)),
     SQLSMALLINT cbConnStrOutMax __attribute__((unused)),
     SQLSMALLINT FAR *pcbConnStrOut __attribute__((unused)));

SQLRETURN SQL_API SQLBrowseConnectW(
    SQLHDBC            hdbc,
    SQLWCHAR        *szConnStrIn,
    SQLSMALLINT        cbConnStrIn,
    SQLWCHAR        *szConnStrOut,
    SQLSMALLINT        cbConnStrOutMax,
    SQLSMALLINT    *pcbConnStrOut)
{
  /*
  this call is not supported but let the ANSI function
  report it
  */
  return SQLBrowseConnect(hdbc, (SQLCHAR *)szConnStrIn, cbConnStrIn,
              (SQLCHAR *)szConnStrOut, cbConnStrOutMax, pcbConnStrOut);
}




SQLRETURN SQL_API SQLColumnPrivilegesW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLWCHAR        *szCatalogName __attribute__((unused)),
    SQLSMALLINT        cbCatalogName __attribute__((unused)),
    SQLWCHAR        *szSchemaName __attribute__((unused)),
    SQLSMALLINT        cbSchemaName __attribute__((unused)),
    SQLWCHAR        *szTableName __attribute__((unused)),
    SQLSMALLINT        cbTableName __attribute__((unused)),
    SQLWCHAR        *szColumnName __attribute__((unused)),
    SQLSMALLINT        cbColumnName __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}

SQLRETURN SQL_API SQLGetStmtAttrW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLINTEGER         fAttribute __attribute__((unused)),
    SQLPOINTER         rgbValue __attribute__((unused)),
    SQLINTEGER         cbValueMax __attribute__((unused)),
    SQLINTEGER     *pcbValue __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}

SQLRETURN SQL_API SQLSetStmtAttrW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLINTEGER         fAttribute __attribute__((unused)),
    SQLPOINTER         rgbValue __attribute__((unused)),
    SQLINTEGER         cbValueMax __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}

SQLRETURN SQL_API SQLForeignKeysW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLWCHAR        *szPkCatalogName __attribute__((unused)),
    SQLSMALLINT        cbPkCatalogName __attribute__((unused)),
    SQLWCHAR        *szPkSchemaName __attribute__((unused)),
    SQLSMALLINT        cbPkSchemaName __attribute__((unused)),
    SQLWCHAR        *szPkTableName __attribute__((unused)),
    SQLSMALLINT        cbPkTableName __attribute__((unused)),
    SQLWCHAR        *szFkCatalogName __attribute__((unused)),
    SQLSMALLINT        cbFkCatalogName __attribute__((unused)),
    SQLWCHAR        *szFkSchemaName __attribute__((unused)),
    SQLSMALLINT        cbFkSchemaName __attribute__((unused)),
    SQLWCHAR        *szFkTableName __attribute__((unused)),
    SQLSMALLINT        cbFkTableName __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}


SQLRETURN SQL_API SQLNativeSqlW(
    SQLHDBC            hdbc __attribute__((unused)),
    SQLWCHAR        *szSqlStrIn __attribute__((unused)),
    SQLINTEGER         cbSqlStrIn __attribute__((unused)),
    SQLWCHAR        *szSqlStr __attribute__((unused)),
    SQLINTEGER         cbSqlStrMax __attribute__((unused)),
    SQLINTEGER     *pcbSqlStr __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}


SQLRETURN SQL_API SQLPrimaryKeysW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLWCHAR        *szCatalogName __attribute__((unused)),
    SQLSMALLINT        cbCatalogName __attribute__((unused)),
    SQLWCHAR        *szSchemaName __attribute__((unused)),
    SQLSMALLINT        cbSchemaName __attribute__((unused)),
    SQLWCHAR        *szTableName __attribute__((unused)),
    SQLSMALLINT        cbTableName __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}

SQLRETURN SQL_API SQLProcedureColumnsW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLWCHAR        *szCatalogName __attribute__((unused)),
    SQLSMALLINT        cbCatalogName __attribute__((unused)),
    SQLWCHAR        *szSchemaName __attribute__((unused)),
    SQLSMALLINT        cbSchemaName __attribute__((unused)),
    SQLWCHAR        *szProcName __attribute__((unused)),
    SQLSMALLINT        cbProcName __attribute__((unused)),
    SQLWCHAR        *szColumnName __attribute__((unused)),
    SQLSMALLINT        cbColumnName __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}

SQLRETURN SQL_API SQLProceduresW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLWCHAR        *szCatalogName __attribute__((unused)),
    SQLSMALLINT        cbCatalogName __attribute__((unused)),
    SQLWCHAR        *szSchemaName __attribute__((unused)),
    SQLSMALLINT        cbSchemaName __attribute__((unused)),
    SQLWCHAR        *szProcName __attribute__((unused)),
    SQLSMALLINT        cbProcName __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}


SQLRETURN SQL_API SQLTablePrivilegesW(
    SQLHSTMT           hstmt __attribute__((unused)),
    SQLWCHAR        *szCatalogName __attribute__((unused)),
    SQLSMALLINT        cbCatalogName __attribute__((unused)),
    SQLWCHAR        *szSchemaName __attribute__((unused)),
    SQLSMALLINT        cbSchemaName __attribute__((unused)),
    SQLWCHAR        *szTableName __attribute__((unused)),
    SQLSMALLINT        cbTableName __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}

SQLRETURN SQL_API SQLDriversW(
    SQLHENV            henv __attribute__((unused)),
    SQLUSMALLINT       fDirection __attribute__((unused)),
    SQLWCHAR        *szDriverDesc __attribute__((unused)),
    SQLSMALLINT        cbDriverDescMax __attribute__((unused)),
    SQLSMALLINT    *pcbDriverDesc __attribute__((unused)),
    SQLWCHAR        *szDriverAttributes __attribute__((unused)),
    SQLSMALLINT        cbDrvrAttrMax __attribute__((unused)),
    SQLSMALLINT    *pcbDrvrAttr __attribute__((unused)))
{
  DBUG_ENTER("");
  DBUG_RETURN_STATUS(SQL_SUCCESS);

}


